Trasmetti Double to Integer in Java


348

Un modo per getto java.lang.Doublea java.lang.Integer?

Genera un'eccezione

"java.lang.ClassCastException: java.lang.Double incompatibile con java.lang.Integer"

Risposte:


464

A Doublenon è un Integer, quindi il cast non funzionerà. Nota la differenza tra la Double classe e la double primitiva . Si noti inoltre che a Doubleè a Number, quindi ha il metodo intValue , che è possibile utilizzare per ottenere il valore come primitiva int.


2
Ok, non fare il cast. Ho bisogno di ottenere l'oggetto Integer da Double, non 13.22222 ma 13, per esempio.
4lex1v,

181
chiama intValue()allora.
hvgotcodes

6
Non dimenticare di gestire i null.
Pimlottc,

13
Nota che questo restituisce semplicemente la parte intera del Double, quindi per 13.666667 o anche 13.9, otterrai 13, non 14. Se vuoi il numero intero più vicino, fai riferimento alla mia risposta: stackoverflow.com/a/24816336/1450294
Michael Scheper,

2
se guardi l'implementazione di intValue(), lancia semplicemente doublea un int.
carlo.marinangeli,

566

È necessario ottenere esplicitamente il valore int usando il metodo intValue () in questo modo:

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

O

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

67
Grazie. Molto chiaro. La risposta accettata, per me, sembra rimproverare di aver fatto una domanda stupida. Ma la tua risposta è molto generosa.
Buddhika Ariyaratne,

2
Cosa succede quando il doppio valore è al di fuori dell'intervallo intero? (come 2 ^ 33)
nikdeapen,

5
Qualsiasi doppio valore> 2^31 - 1 (Integer.MAX_VALUE)trabocca.
anubhava,

3
E, a proposito, quando viene lanciato da double a int, mantiene solo la parte intera, sia per i numeri positivi che per quelli negativi, e non si preoccupa degli arrotondamenti. ad esempio 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Eric Wang

51

Penso che sia impossibile capire le altre risposte senza coprire le insidie ​​e il ragionamento dietro di essa.

Non è possibile trasmettere direttamente Integerun Doubleoggetto. Inoltre Doublee Integersono oggetti immutabili, quindi non puoi modificarli in alcun modo.

Ogni classe numerica ha un'alternativa primitiva ( Doublevs double, Integervs int, ...). Nota che queste primitive iniziano con un carattere minuscolo (ad es int.). Questo ci dice che non sono classi / oggetti. Ciò significa anche che non hanno metodi. Al contrario, le classi (ad es. Integer) Agiscono come scatole / involucri attorno a queste primitive, il che rende possibile usarle come oggetti.

Strategia:

Per convertire un Doublein un Integerdevi seguire questa strategia:

  1. Converti l' Doubleoggetto in una primitiva double. (= "unboxing")
  2. Converti la primitiva doublein primitiva int. (= "casting")
  3. Converti la primitiva intin un Integeroggetto. (= "boxe")

Nel codice:

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

In realtà c'è una scorciatoia. Puoi decomprimere immediatamente da una Doublescala a una primitiva int. In questo modo, puoi saltare completamente il passaggio 2.

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

insidie:

Tuttavia, ci sono molte cose che non sono trattate nel codice sopra. Il codice sopra non è sicuro.

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

Ora funziona bene per la maggior parte dei valori. Tuttavia, i numeri interi hanno un intervallo molto piccolo (valore min / max) rispetto a a Double. Inoltre, i doppi possono contenere anche "valori speciali", che i numeri interi non possono:

  • 1/0 = + infinito
  • -1/0 = -infinito
  • 0/0 = non definito (NaN)

Quindi, a seconda dell'applicazione, potresti voler aggiungere alcuni filtri per evitare brutte eccezioni.

Quindi, il prossimo difetto è la strategia di arrotondamento. Per impostazione predefinita, Java verrà sempre arrotondato per difetto. L'arrotondamento ha perfettamente senso in tutti i linguaggi di programmazione. Fondamentalmente Java sta buttando via alcuni byte. Nelle applicazioni finanziarie vorrai sicuramente usare l'arrotondamento per metà (ad esempio: round(0.5) = 1e 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-(ONU) di pugilato

Potresti essere tentato di usare l' auto- (un) boxing in questo, ma non lo farei. Se sei già bloccato ora, i prossimi esempi non saranno nemmeno così ovvi. Se non capisci il funzionamento interno del boxing automatico (non), ti preghiamo di non usarlo.

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)

Immagino che quanto segue non dovrebbe essere una sorpresa. Ma se lo è, allora potresti voler leggere alcuni articoli sul casting in Java.

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

Preferisci valore di:

Inoltre, non essere tentato di usare il new Integer()costruttore (come suggeriscono altre risposte). I valueOf()metodi sono migliori perché utilizzano la memorizzazione nella cache. È una buona abitudine usare questi metodi, perché di tanto in tanto ti risparmieranno un po 'di memoria.

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

1
questa secondo me è la risposta migliore
Thor

39

Vedo tre possibilità. I primi due tagliano le cifre, l'ultimo arriva al numero intero più vicino.

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
Non è necessario Integer.valueOf se si intende archiviare il risultato in una primitieve int. Il codice impone a Java di eseguire una casella e unbox non necessari.
bvdb,


23

In effetti, il modo più semplice è usare intValue(). Tuttavia, ciò restituisce semplicemente la parte intera; non fa alcun arrotondamento. Se desideri che il numero intero sia il più vicino al valore Double, dovrai farlo:

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

E non dimenticare il caso nullo:

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

Math.round() gestisce casi di anatre dispari, come infinito e NaN, con relativa grazia.


2
Perché hai bisogno di Integer.valueOf se lanci il risultato Math.round su int?
Eran H.

@EranH .: A partire da Java 1.5, probabilmente no: l'autoboxing significa che probabilmente il codice finisce per fare la stessa cosa in entrambi i modi. Ma penso che questo codice sia più chiaro per le persone che non hanno ancora afferrato oggetti e primitive.
Michael Scheper,

Chiunque abbia votato in negativo questa risposta: aiuterai la comunità molto di più se spieghi il perché e potrebbe anche aiutarti a scoprire perché non ha funzionato per te. Il voto negativo senza spiegazione, OTOH, non è di aiuto per tutti, e si presenta come un codardo.
Michael Scheper,

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

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

2
La domanda riguardava specificamente le classi wrapper. Questa risposta riguarda i primitivi.
Michael Scheper,

8

Fallo semplicemente in questo modo ...

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

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

Si dovrebbe anche aggiungere che funziona con l'autoboxing.

Altrimenti, ottieni un int (primitivo) e quindi puoi ottenere un intero da lì:

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

2
Non usare new Integer(int), invece usa Integer.valueOf(int), che ha una cache per numeri interi piccoli, come questo.
bvdb,


4

Puoi farlo usando "Restringimento o conversione del tipo esplicito", doppio → lungo → int. Spero che funzioni.

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

PS: darà 0 come doppio con tutti i valori decimali e niente sul lato sinistro. In caso di 0,58, lo restringerà a 0. Ma per altri farà la magia.


4

Prova questo

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

3

Double e Integer sono classi wrapper per le primitive Java rispettivamente per double e int. Puoi lanciare tra quelli, ma perderai il virgola mobile. Cioè, 5.4 lanciato su un int sarà 5. Se lo rilasci, sarà 5.0.


0

Usa semplicemente il metodo intValue di Double

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

2
Sembra una ripetizione delle altre risposte.
Pang

0

Usa il doubleNumber.intValue();metodo


2
Sembra una ripetizione delle altre risposte.
Pang

-1

Memoria efficiente, in quanto condividerà l'istanza già creata di Double.

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

c'è qualche motivo per Math.floor(...)? intValue()sempre piani comunque.
bvdb,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.