用Java将Double转换为Integer


347

任何方式投java.lang.Doublejava.lang.Integer

引发异常

“ java.lang.ClassCastException:java.lang.Double与java.lang.Integer不兼容”

Answers:


463

A Double不是Integer,因此强制转换将不起作用。请注意Double double 原始类型之间的区别。另请注意,a Double是a Number因此它具有方法 intValue,您可以使用该方法将值作为原始值获取int


2
好的,不要投。我需要从Double获取Integer对象,例如,不是13.22222,而是13。
4lex1v 2012年

181
intValue()然后打电话。
hvgotcodes'2

6
不要忘记处理null。
pimlottc 2014年

13
请注意,这只是返回Double的整数部分,因此对于13.666667甚至13.9,你会得到13,而不是14,如果你想在最近的整数,请参阅我的回答:stackoverflow.com/a/24816336/1450294
Michael Scheper 2014年

2
如果您看一下的实现intValue(),它只会将强制转换doubleint
carlo.marinangeli 2015年

564

您需要使用方法intValue()显式获取int值,如下所示:

Double d = 5.25;
Integer i = d.intValue(); // i becomes 5

要么

double d = 5.25;
int i = (int) d;

67
谢谢。非常清楚。对我来说,被接受的答案就像是在问一个愚蠢的问题一样在责骂。但是您的答案非常慷慨。
Buddhika Ariyaratne 2014年

2
当double值超出整数范围时会发生什么?(例如2 ^ 33)
nikdeapen 2014年

5
任何double值> 2^31 - 1 (Integer.MAX_VALUE)都会溢出。
anubhava 2014年

3
而且,顺便说一下,当从double转换为int时,对于正数和负数,它仅保留整数部分,并且不关心舍入。例如1.6 -> 11.4 -> 1-1.6 -> -1-1.4 -> -1
埃里克·王

51

我认为,如果不掩盖陷阱和背后的推理,就不可能理解其他答案。

您不能直接将投射IntegerDouble对象。也DoubleInteger是不可变的对象,因此您不能以任何方式修改它们。

每个数字都有一个原始的替代项(Doublevs doubleIntegervs int,...)。请注意,这些原语以小写字母(例如int)开头。这就告诉我们它们不是类/对象。这也意味着他们没有方法。相比之下,类(例如Integer)的作用就像是围绕这些基元的盒子/包装器,这使得可以像使用对象一样使用它们。

战略:

要将a转换Double为an,Integer您需要遵循以下策略:

  1. Double对象转换为基本体double。(=“取消装箱”)
  2. 将图元转换为图doubleint。(=“广播”)
  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

陷阱:

但是,上面的代码中没有很多内容。上面的代码不是null安全的。

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());

现在,它适用于大多数值。但是,与a相比,整数的范围(最小值/最大值)非常小Double。最重要的是,双精度也可以保存“特殊值”,而整数不能:

  • 1/0 = +无穷大
  • -1/0 =-无穷大
  • 0/0 =未定义(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

39

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

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

21
如果要将结果存储在primitieve int中,则不需要Integer.valueOf。您的代码会强制Java执行不必要的装箱和拆箱。
bvdb 2015年


23

确实,最简单的方法是使用intValue()。但是,这仅返回整数部分。它不做任何舍入。如果要使Integer 最接近 Double值,则需要执行以下操作:

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

并且不要忘记null情况:

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

Math.round() 相对宽限地处理诸如Infinity和NaN之类的奇怪鸭子情况。


2
如果将Math.round结果转换为int,为什么需要Integer.valueOf?
Eran H.

@EranH .:从Java 1.5开始,您可能不知道—自动装箱意味着代码最终可能以两种方式完成相同的操作。但是我认为对于尚未完全掌握对象和基元的人们来说,这段代码更加清晰。
Michael Scheper 2015年

谁会否决这个答案:如果您解释原因,您将为社区提供更多帮助,甚至可能帮助您找出它对您不起作用的原因。OTOH不加解释地拒绝投票对每个人都无济于事,而且胆怯。
Michael Scheper '18

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

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

2
问题特别是关于包装器类的。这个答案是关于基元的。
Michael Scheper 2014年


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 2014年


4

您可以使用“变窄或显式类型转换”,双击→long→int。我希望它能起作用。

double d = 100.04;
long l = (long)d; // Explicit type casting required
int i = (int)l;    // Explicit type casting required

PS:它将给出0,因为double具有所有十进制值,而左侧没有任何内容。在0.58的情况下,它会将其范围缩小到0。但是对于其他人,它将起到神奇作用。



3

Double和Integer分别是double和int的Java原语的包装器类。您可以在两者之间进行转换,但是会丢失浮点数。也就是说,将5.4强制转换为int将为5。如果将其强制强制转换为5.0。


0

只需使用Double的intValue方法

Double initialValue = 7.12;
int finalValue = initialValue.intValue();

2
似乎是其他答案的重复。

0

使用doubleNumber.intValue();方法。


2
似乎是其他答案的重复。

-1

高效的内存,因为它将共享已经创建的Double实例。

Double.valueOf(Math.floor(54644546464/60*60*24*365)).intValue()

有什么原因Math.floor(...)吗? intValue()无论如何总是地板。
bvdb '19

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.