Передайте подвійний до цілого числа на Java


348

Будь-який спосіб лиття java.lang.Doubleз java.lang.Integer?

Це кидає виняток

"java.lang.ClassCastException: java.lang.Double несумісний з java.lang.Integer"

Відповіді:


464

A 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
Дякую. Дуже ясно. Прийнята відповідь мені здається негідною, коли я задаю дурне запитання. Але ваша відповідь дуже щедра.
Buddhika Ariyaratne

2
Що відбувається, коли подвійне значення знаходиться поза цілим діапазоном? (як 2 ^ 33)
nikdeapen

5
Будь-яке подвійне значення> 2^31 - 1 (Integer.MAX_VALUE)переповниться.
анубхава

3
І, до речі, при передачі від подвійного до цілого, він зберігає лише цілу частину як для позитивних, так і для негативних чисел, і не хвилює округлення. наприклад 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Ерік Ван

51

Я думаю, що неможливо зрозуміти інші відповіді, не висвітлюючи підводні камені та міркування .

Ви не можете безпосередньо Integerнадати Doubleоб’єкт. Також DoubleіInteger є незмінними об'єктами, так що ви не можете змінити їх в будь-якому випадку.

Кожен числовий клас має примітивну альтернативу ( Doublevs double, Integervs 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());

Тепер він працює чудово для більшості цінностей. Однак цілі числа мають дуже малий діапазон (значення min / max) порівняно з a Double. Крім того, парні також можуть містити "спеціальні значення", що цілі числа не можуть:

  • 1/0 = + нескінченність
  • -1/0 = -безмінність
  • 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

Переважне значенняOf:

Крім того, не спокушайтеся використовувати 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, якщо ви збираєтеся зберігати результат у примітці primitieve. Ваш код змушує Java виконувати непотрібну скриньку та відключити.
bvdb


23

Дійсно, найпростіший спосіб - це використовувати intValue(). Однак це лише повертає цілу частину; це не робить жодного округлення. Якщо ви хочете, щоб ціле число було найближчим до значення Подвійний, вам потрібно зробити це:

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

Це можна зробити, скориставшись "Звуженням або явним перетворенням типу", подвійним → довгим → int. Сподіваюся, це спрацює.

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

PS: Він дасть 0, оскільки у подвійних значень є всі десяткові значення і нічого немає з лівого боку. У випадку 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()завжди підлоги все одно.
bvdb

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.