Я думаю, что невозможно понять другие ответы без учета ловушек и аргументации за этим.
Вы не можете напрямую привести Integer
к Double
объекту. Также Double
и Integer
являются неизменяемыми объектами, поэтому вы не можете их изменять каким-либо образом.
Каждый числовой класс имеет альтернативу примитив (Double
против double
, Integer
против int
, ...). Обратите внимание, что эти примитивы начинаются со строчной буквы (например, int
). Это говорит нам о том, что они не являются классами / объектами. Что также означает, что у них нет методов. Напротив, классы (например, Integer
) действуют как коробки / обертки вокруг этих примитивов, что позволяет использовать их как объекты.
Стратегия:
Чтобы преобразовать Double
в Integer
, вам необходимо придерживаться этой стратегии:
- Преобразовать объект
Double
в примитив double
. (= "распаковка")
- Преобразовать примитив
double
в примитив int
. (= "кастинг")
- Преобразовать примитив
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);
Автомототехника (ип) бокс
У вас может возникнуть соблазн использовать auto- (un) boxing , но я бы не стал. Если вы уже застряли сейчас, то и следующие примеры не будут такими очевидными. Если вы не понимаете внутреннюю работу авто (не) бокса, то, пожалуйста, не используйте его.
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
Предпочтительное значениеOf:
Кроме того, не поддавайтесь искушению использовать конструктор new Integer()
(как предлагают некоторые другие ответы). Методы valueOf()
лучше, потому что они используют кеширование. Это хорошая привычка использовать эти методы, потому что время от времени они сохраняют вам немного памяти.
long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = new Integer(rounded); // waste of memory