Java中将Double转换为Integer

379

有没有办法将java.lang.Double转换为java.lang.Integer

它会抛出一个异常

"java.lang.ClassCastException: java.lang.Double不兼容于java.lang.Integer"

19个回答

590

你需要使用方法intValue()显式地获取int值,就像这样:

Double d = 5.25;
Integer i = d.intValue(); // i becomes 5
或者
double d = 5.25;
int i = (int) d;

493

Double不是一个Integer,所以强制转换是无法工作的。注意Double类和double原始类型之间的区别。还要注意Double是一个Number所以它有方法intValue,你可以使用它将值作为原始int获取。


2
不需要进行强制类型转换。我需要从Double获取Integer对象,例如不是13.22222而是13。 - 4lex1v
197
只需调用 intValue() 即可。 - hvgotcodes
7
别忘了处理空值。 - pimlottc
14
请注意,此函数仅返回Double类型的整数部分,因此对于13.666667甚至13.9,它将返回13而不是14。如果您想要最接近的整数,请参考我的答案:https://dev59.com/mGox5IYBdhLWcg3wmFWV#24816336 - Michael Scheper
2
如果您查看intValue()的实现,它只是将double强制转换为int - carlo.marinangeli
显示剩余2条评论

60
我认为,如果不涉及其中的陷阱和推理,就无法理解其他答案。
您不能直接将Integer转换为Double对象。此外,DoubleInteger是不可变对象,因此您无法以任何方式修改它们。
每个数字都有一个基本类型Double vs double, Integer vs int, ...)。请注意,这些基本类型以小写字符开头(例如int),这告诉我们它们不是类/对象。这也意味着它们没有方法。相比之下,类(例如Integer)就像围绕这些基本类型的盒子/包装器,这使得可以像使用对象一样使用它们。

策略:

要将Double转换为Integer,您需要遵循以下策略:
  1. Double对象转换为基本类型double。(=“拆箱”)
  2. 将基本类型double转换为基本类型int。(=“强制类型转换”)
  3. 将基本类型int再次转换为Integer对象。(=“装箱”)

代码示例:

// starting point
Double myDouble = Double.valueOf(10.0);

// step 1: unboxing
double dbl = myDouble.doubleValue();

// step 2: casting
int intgr = (int) dbl;

// step 3: boxing
Integer val = Integer.valueOf(intgr);

实际上有一种捷径。您可以直接将Double转换为原始的int,这样就可以完全跳过第2步。

Double myDouble = Double.valueOf(10.0);
Integer val = Integer.valueOf(myDouble.intValue()); // the simple way

注意事项:

然而,上述代码并未涵盖所有情况。 上述代码不具备空值安全性。

Double myDouble = null;
Integer val = Integer.valueOf(myDouble.intValue()); // will throw a NullPointerException

// a null-safe solution:
Integer val = (myDouble == null)? null : Integer.valueOf(myDouble.intValue());

现在它对大多数值都可以正常工作。但是与 Double 相比,整数的范围非常小(最小/最大值)。此外,双精度浮点数还可以保存整数不行的“特殊值”:
  • 1/0 = +infinity
  • -1/0 = -infinity
  • 0/0 = undefined (NaN)
因此,根据应用程序的不同,您可能希望添加一些过滤以避免出现异常情况。
然后,下一个缺点是舍入策略。默认情况下,Java 总是向下取整。向下取整在所有编程语言中都很有道理。基本上,Java 只是抛弃了一些字节。在财务应用程序中,您肯定会想使用半进位舍入(例如:round(0.5) = 1round(0.4) = 0)。
// null-safe and with better rounding
long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = Integer.valueOf(rounded);

自动装箱和拆箱

在这里,你可能会被诱惑使用自动装箱和拆箱,但我不建议这样做。如果你现在已经遇到了问题,那么下面的例子也不会更加明显。如果你不理解自动装箱和拆箱的内部机制,请不要使用它。

Integer val1 = 10; // works
Integer val2 = 10.0; // doesn't work

Double val3 = 10; // doesn't work
Double val4 = 10.0; // works

Double val5 = null; 
double val6 = val5; // doesn't work (throws a NullPointerException)

我猜下面的内容不应该让你感到惊讶。但如果确实让你感到惊讶,那么你可能需要阅读一些有关Java中类型转换的文章。
double val7 = (double) 10; // works
Double val8 = (Double) Integer.valueOf(10); // doesn't work
Integer val9 = (Integer) 9; // pure nonsense

优先使用valueOf方法:

同时,不要被一些其他答案所提出的使用new Integer()构造器所诱惑。因为valueOf()方法使用缓存,所以它们更好。使用这些方法是一个好习惯,因为有时它们会节省一些内存。

long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = new Integer(rounded); // waste of memory

1
这是我认为最好的答案。 - Thor

41

我看到三种可能性。前两种会截去数字,最后一种会四舍五入到最近的整数。

double d = 9.5;
int i = (int)d;
//i = 9

Double D = 9.5;
int i = Integer.valueOf(D.intValue());
//i = 9

double d = 9.5;
Long L = Math.round(d);
int i = Integer.valueOf(L.intValue());
//i = 10

23
如果你打算将结果存储在原始的int类型中,那么就没有必要使用Integer.valueOf。你的代码会强制Java执行不必要的装箱和拆箱操作。 - bvdb

24

事实上,最简单的方法是使用intValue()。但是,这只返回整数部分,不进行任何取整。如果您想要最接近Double值的整数,则需要执行以下操作:

Integer integer = Integer.valueOf((int) Math.round(myDouble)));

不要忘记空值情况:

Integer integer = myDouble == null ? null : Integer.valueOf((int) Math.round(myDouble)));

Math.round()可以相对优雅地处理无穷大和NaN等异常情况。


2
如果您将Math.round结果转换为int,为什么需要使用Integer.valueOf? - Eran H.
自Java 1.5起,您可能不需要这样做 - 自动装箱意味着代码最终可能以相同的方式运行。但我认为对于还没有完全掌握对象和基本类型的人来说,这段代码更清晰易懂。 - Michael Scheper
谁给这个答案点了踩:如果你能解释一下为什么,那么你会更有助于社区,甚至可能帮助你找出它为什么不起作用。相反,没有解释的踩是对每个人都没有帮助的,而且显得很懦弱。 - Michael Scheper

23

就像这样:

Double foo = 123.456;
Integer bar = foo.intValue();

14
double a = 13.34;
int b = (int) a;

System.out.println(b); //prints 13

2
这个问题特别涉及到包装类。而这个答案是关于基本类型的。 - Michael Scheper

8

只需按照以下方式操作...

Double d = 13.5578;
int i = d.intValue();
System.out.println(i);

7
Double d = 100.00;
Integer i = d.intValue();

需要补充的是它支持自动装箱。

否则,你会得到一个int(原始类型),然后可以从中获取一个Integer:

Integer i = new Integer(d.intValue());

2
不要使用new Integer(int),而应该使用Integer.valueOf(int),它针对小整数(如此)有缓存。 - bvdb

6

在你的Double对象上调用intValue()方法。


2
似乎是之前答案的重复。 - Pang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接