Приведите Double к Integer в Java


348

Любой способ привести java.lang.Doubleк java.lang.Integer?

Это исключение

"java.lang.ClassCastException: java.lang. Double несовместим с java.lang.Integer"

Ответы:


464

А Doubleне является Integer, поэтому актерский состав не будет работать. Обратите внимание на разницу между Double классом и double примитивом . Также обратите внимание, что a Doubleявляется a Number, поэтому у него есть метод intValue , который можно использовать для получения значения в качестве примитива int.


2
Хорошо, не бросать. Мне нужно получить объект Integer из Double, не 13.22222, а 13, например.
4lex1v

181
просто позвони intValue()тогда.
hvgotcodes

6
Не забудьте обработать нули.
pimlottc

13
Обратите внимание, что это просто возвращает целочисленную часть Double, поэтому для 13.666667 или даже 13.9 вы получите 13, а не 14. Если вам нужно ближайшее целое число, обратитесь к моему ответу: stackoverflow.com/a/24816336/1450294
Майкл Шепер

2
если вы посмотрите на реализацию intValue(), он просто doubleприводит к int.
carlo.marinangeli

566

Вам нужно явно получить значение int, используя метод intValue (), например:

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

Или

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

67
Спасибо. Очень ясно. Принятый ответ для меня, похоже, ругает за глупый вопрос. Но ваш ответ очень щедрый.
Будика Арияратне

2
Что происходит, когда значение double находится вне целочисленного диапазона? (как 2 ^ 33)
nikdeapen

5
Любое двойное значение> 2^31 - 1 (Integer.MAX_VALUE)будет переполнено.
анубхава

3
И, кстати, при приведении от double к int он сохраняет только целую часть, как для положительных, так и для отрицательных чисел, и не заботится о округлении. например 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Эрик Ван

51

Я думаю, что невозможно понять другие ответы, не скрывая ошибок и рассуждений .

Вы не можете напрямую привести объект Integerк Doubleобъекту. Также DoubleиInteger являются неизменяемыми объектами, поэтому вы не можете их никоим образом изменять.

Каждый числовой класс имеет примитивную альтернативу ( Doublevs double, Integervs int, ...). Обратите внимание, что эти примитивы начинаются со строчной буквы (например, int). Это говорит нам о том, что они не являются классами / объектами. Что также означает, что у них нет методов. В отличие от классов (например,Integer ) действуют как коробки / оболочки вокруг этих примитивов, что позволяет использовать их как объекты.

Стратегия:

Чтобы преобразовать a Doubleв a 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. Кроме того, double также может содержать «специальные значения», которые целые числа не могут:

  • 1/0 = + бесконечность
  • -1/0 = -infinity
  • 0/0 = не определено (NaN)

Поэтому, в зависимости от приложения, вы можете захотеть добавить фильтрацию, чтобы избежать неприятных исключений.

Тогда следующим недостатком является стратегия округления. По умолчанию Java всегда будет округляться. Округление вниз имеет смысл во всех языках программирования. По сути, Java просто отбрасывает некоторые байты. В финансовых приложениях вы наверняка захотите использовать округление до половины (например: round(0.5) = 1и round(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
это, на мой взгляд, лучший ответ
Тор

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
Integer.valueOf не нужен, если вы собираетесь хранить результат в примитиве int. Ваш код заставляет Java выполнять ненужные блоки и распаковывать.
bvdb


23

Действительно, самый простой способ - это использовать intValue(). Однако это просто возвращает целочисленную часть; это не делает никакого округления. Если вы хотите, чтобы Integer ближайший к значению Double, вам нужно сделать это:

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

И не забывайте нулевой случай:

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

Math.round() обрабатывает странные случаи утки, как бесконечность и NaN, с относительной грацией.


2
Зачем вам нужен Integer.valueOf, если вы приводите Math.round результат к int?
Эран Х.

@EranH .: Начиная с Java 1.5, вы, вероятно, этого не делаете - автобокс означает, что код, скорее всего, в любом случае будет делать то же самое. Но я думаю, что этот код более понятен для людей, которые еще не совсем поняли объекты и примитивы.
Майкл Шепер

Кто бы ни отрицал этот ответ: Вы поможете сообществу намного больше, если объясните почему, и это может даже помочь вам выяснить, почему это не работает для вас. Голосование без объяснения причин, OTOH, бесполезно для всех, и это выглядит как трусливое.
Майкл Шепер



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


4

Вы можете сделать это, используя «Сужение или явное преобразование типов», double → 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 являются классами-обертками для примитивов Java для double и int соответственно. Вы можете разыгрывать между ними, но вы потеряете плавающую точку. То есть 5.4, приведенное к int, будет 5. Если вы приведете его обратно, это будет 5.0.


0

Просто используйте метод intValue Double

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()всегда полы в любом случае.
19

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.