Rzuć Double na Integer w Javie


348

Jakikolwiek sposób do obsady java.lang.Doubledo java.lang.Integer?

Zgłasza wyjątek

„java.lang.ClassCastException: java.lang.Double niezgodny z java.lang.Integer”

Odpowiedzi:


464

A Doublenie jest Integer, więc obsada nie będzie działać. Zwróć uwagę na różnicę między Double klasą a double prymitywem . Zauważ też, że a Doublejest a Number, więc ma metodę intValue , której możesz użyć, aby uzyskać wartość jako prymityw int.


2
Ok nie rzucać. Potrzebuję uzyskać obiekt typu Integer z Double, nie 13.22222, ale na przykład 13.
4lex1v

181
po prostu zadzwoń intValue().
hvgotcodes

6
Nie zapomnij obsłużyć zer.
pimlottc

13
Zauważ, że to tylko zwraca liczbę całkowitą Double, więc dla 13.666667, a nawet 13,9, dostaniesz 13, a nie 14. Jeśli chcesz najbliższej liczby całkowitej, zapoznaj się z moją odpowiedzią: stackoverflow.com/a/24816336/1450294
Michael Scheper

2
jeśli spojrzeć na realizację intValue(), po prostu rzuca doublesię int.
carlo.marinangeli

566

Musisz jawnie uzyskać wartość int za pomocą metody intValue () w następujący sposób:

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

Lub

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

67
Dziękuję Ci. Bardzo czyste. Dla mnie zaakceptowana odpowiedź brzmi jak karanie za zadawanie głupich pytań. Ale twoja odpowiedź jest bardzo hojna.
Buddhika Ariyaratne

2
Co dzieje się, gdy podwójna wartość jest poza zakresem liczb całkowitych? (jak 2 ^ 33)
nikdeapen

5
Każda podwójna wartość> 2^31 - 1 (Integer.MAX_VALUE)przepełni się.
anubhava

3
Nawiasem mówiąc, po rzutowaniu z podwójnej na całkowitą zachowuje tylko część całkowitą, zarówno dla liczb dodatnich, jak i ujemnych, i nie przejmuje się zaokrąglaniem. np 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Eric Wang

51

Myślę, że niemożliwe jest zrozumienie innych odpowiedzi bez uwzględnienia pułapek i uzasadnienia .

Nie możesz bezpośrednio rzutować Integerna Doubleobiekt. Również Doublei Integersą niezmienne obiekty, więc nie można ich modyfikować w dowolny sposób.

Każda klasa liczbowa ma prymitywną alternatywę ( Doublevs double, Integervs int, ...). Zauważ, że te prymitywy zaczynają się od małych liter (np int.). To mówi nam, że nie są klasami / obiektami. Co oznacza również, że nie mają metod. Natomiast klasy (np. Integer) Działają jak pudełka / opakowania wokół tych prymitywów, co umożliwia ich użycie jako obiektów.

Strategia:

Aby przekonwertować Doublena a Integer, musisz przestrzegać tej strategii:

  1. Przekształć Doubleobiekt w prymityw double. (= „unboxing”)
  2. Konwertuj prymityw doublena prymityw int. (= „casting”)
  3. Konwertuj prymityw z intpowrotem na Integerobiekt. (= „boks”)

W kodzie:

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

W rzeczywistości istnieje skrót. Możesz natychmiast rozpakować z Doubleprostej do prymitywnej int. W ten sposób możesz całkowicie pominąć krok 2.

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

Pułapki:

Istnieje jednak wiele rzeczy, które nie zostały omówione w powyższym kodzie. Powyższy kod nie jest bezpieczny.

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

Teraz działa dobrze dla większości wartości. Jednak liczby całkowite mają bardzo mały zakres (wartość min./maks.) W porównaniu do a Double. Ponadto w liczbach podwójnych mogą znajdować się także „wartości specjalne”, których liczby całkowite nie mogą:

  • 1/0 = + nieskończoność
  • -1/0 = nieskończoność
  • 0/0 = niezdefiniowany (NaN)

W zależności od aplikacji możesz dodać filtrowanie, aby uniknąć nieprzyjemnych wyjątków.

Kolejnym niedociągnięciem jest strategia zaokrąglania. Domyślnie Java zawsze będzie zaokrąglać w dół. Zaokrąglanie w dół ma sens we wszystkich językach programowania. Zasadniczo Java po prostu wyrzuca niektóre bajty. W aplikacjach finansowych na pewno będziesz chciał użyć zaokrąglania o pół w górę (np .: round(0.5) = 1i round(0.4) = 0).

// null-safe and with better rounding
long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = Integer.valueOf(rounded);

Boks automatyczny (un)

Możesz mieć pokusę, aby użyć do tego automatycznego (lub) boksu , ale nie zrobiłbym tego. Jeśli utknąłeś już teraz, kolejne przykłady również nie będą tak oczywiste. Jeśli nie rozumiesz wewnętrznych zasad automatycznego (lub) boksu, nie używaj go.

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)

Myślę, że poniższe rzeczy nie powinny być zaskoczeniem. Ale jeśli tak, to możesz przeczytać artykuł o przesyłaniu w Javie.

double val7 = (double) 10; // works
Double val8 = (Double) Integer.valueOf(10); // doesn't work
Integer val9 = (Integer) 9; // pure nonsense

Preferuj wartość:

Nie kusz też, aby użyć new Integer()konstruktora (jak sugerują inne odpowiedzi). Te valueOf()metody są lepsze, ponieważ używają buforowania. Dobrym nawykiem jest używanie tych metod, ponieważ od czasu do czasu oszczędzają ci trochę pamięci.

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

1
to moim zdaniem najlepsza odpowiedź
Thor

39

Widzę trzy możliwości. Pierwsze dwa odcinają cyfry, ostatni zaokrągla do najbliższej liczby całkowitej.

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
Nie ma potrzeby używania Integer.valueOf, jeśli zamierzasz zapisać wynik w primitieve int. Twój kod zmusza Javę do wykonania niepotrzebnego pudła i rozpakowania.
bvdb


23

Rzeczywiście, najprostszym sposobem jest użycie intValue(). Zwraca to jednak tylko część całkowitą; nie zaokrągla. Jeśli chcesz, aby liczba całkowita była najbliższa wartości Double, musisz to zrobić:

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

I nie zapomnij o zerowym przypadku:

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

Math.round() obsługuje nieparzyste przypadki kaczek, takie jak nieskończoność i NaN, ze względną gracją.


2
Dlaczego potrzebujesz Integer.valueOf, jeśli rzutujesz wynik Math.round na int?
Eran H.,

@EranH .: Od wersji Java 1.5 prawdopodobnie tego nie robisz - autoboxing oznacza, że ​​kod prawdopodobnie i tak robi to samo. Ale myślę, że ten kod jest wyraźniejszy dla osób, które jeszcze nie do końca zrozumiały obiekty i prymitywy.
Michael Scheper,

Ktokolwiek zlekceważył tę odpowiedź: znacznie bardziej pomożesz społeczności, jeśli wyjaśnisz dlaczego, a może nawet pomoże ci dowiedzieć się, dlaczego to nie zadziałało. Głosowanie w dół bez wyjaśnienia, OTOH, nie jest pomocne dla wszystkich i wydaje się tchórzliwe.
Michael Scheper,

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

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

2
Pytanie dotyczyło konkretnie klas opakowań. Ta odpowiedź dotyczy prymitywów.
Michael Scheper,

8

Po prostu zrób to w ten sposób ...

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

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

Należy również dodać, że działa z autoboxingiem.

W przeciwnym razie otrzymasz liczbę całkowitą (pierwotną), a następnie możesz uzyskać liczbę całkowitą:

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

2
Nie używaj new Integer(int), zamiast tego używaj Integer.valueOf(int), który ma pamięć podręczną dla małych liczb całkowitych, takich jak ta.
bvdb


4

Można to zrobić za pomocą „Konwersji typu Zawężenie lub Jawne”, podwójne → długie → int. Mam nadzieję, że to zadziała.

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

PS: Daje 0, ponieważ double ma wszystkie wartości dziesiętne i nic po lewej stronie. W przypadku 0,58 zawęzi to do 0. Ale dla innych zrobi magię.


4

Spróbuj tego

double doubleValue = 6.5;Double doubleObj = new Double(doubleValue);int intResult = doubleObj.intValue();

3

Double i Integer są klasami opakowań dla prymitywów Java odpowiednio dla double i int. Możesz rzucać między nimi, ale stracisz zmiennoprzecinkowy. Oznacza to, że 5,4 rzutowane na int będzie wynosić 5. Jeśli rzucisz go z powrotem, będzie to 5.0.


0

Po prostu użyj metody intValue Double

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

2
Wygląda na powtórzenie pozostałych odpowiedzi.
Pang

0

Skorzystaj z doubleNumber.intValue();metody


2
Wygląda na powtórzenie pozostałych odpowiedzi.
Pang

-1

Wydajna pamięć, ponieważ będzie współdzielić utworzoną już instancję Double.

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

czy jest jakiś powód Math.floor(...)? intValue()i tak zawsze podłogi.
bvdb

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.