Cast Double to Integer en Java

348

Cualquier forma de fundido java.lang.Doublea java.lang.Integer?

Lanza una excepción

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

4lex1v
fuente

Respuestas:

464

A Doubleno es un Integer, por lo que el elenco no funcionará. Tenga en cuenta la diferencia entre la Double clase y la double primitiva . También tenga en cuenta que a Doublees a Number, por lo que tiene el método intValue , que puede usar para obtener el valor como primitivo int.

hvgotcodes
fuente
2
Ok no para lanzar. Necesito obtener un objeto Integer de Double, no 13.22222 sino 13, por ejemplo.
4lex1v
181
solo llama intValue()entonces.
hvgotcodes 01 de
66
No olvides manejar nulos.
pimlottc
13
Tenga en cuenta que esto simplemente devuelve la parte entera del Doble, por lo que para 13.666667 o incluso 13.9, obtendrá 13, no 14. Si desea el entero más cercano , consulte mi respuesta: stackoverflow.com/a/24816336/1450294
Michael Scheper
2
si miras la implementación de intValue(), solo convierte el doublea int.
carlo.marinangeli
566

Debe obtener explícitamente el valor int utilizando el método intValue () de esta manera:

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

O

double d = 5.25;
int i = (int) d;
anubhava
fuente
67
Gracias. Muy claro. La respuesta aceptada, para mí, se siente como regañar por hacer una pregunta tonta. Pero tu respuesta es muy generosa.
Buddhika Ariyaratne
2
¿Qué sucede cuando el valor doble está fuera del rango entero? (como 2 ^ 33)
nikdeapen
55
Cualquier valor doble> 2^31 - 1 (Integer.MAX_VALUE)se desbordará.
Anubhava
3
Y, por cierto, cuando se convierte de doble a int, solo mantiene la parte entera, tanto para números positivos como negativos, y no le importa redondear. por ejemplo 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Eric Wang
51

Creo que es imposible entender las otras respuestas sin cubrir las trampas y el razonamiento detrás de esto.

No se puede lanzar directamente Integera un Doubleobjeto. También Doubley Integerson objetos inmutables, por lo que no puede modificarlos de ninguna manera.

Cada clase numérica tiene una alternativa primitiva ( Doublevs double, Integervs int, ...). Tenga en cuenta que estas primitivas comienzan con un carácter en minúscula (por ejemplo int). Eso nos dice que no son clases / objetos. Lo que también significa que no tienen métodos. Por el contrario, las clases (p Integer. Ej. ) Actúan como cajas / envoltorios alrededor de estas primitivas, lo que hace posible usarlas como objetos.

Estrategia:

Para convertir un Doublea Integer, necesitaría seguir esta estrategia:

  1. Convierte el Doubleobjeto en un primitivo double. (= "unboxing")
  2. Convierta lo primitivo doubleen primitivo int. (= "casting")
  3. Convierta la primitiva de intnuevo en un Integerobjeto. (= "boxeo")

En codigo:

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

En realidad hay un atajo. Puede desempaquetar inmediatamente de un Doubledirecto a un primitivo int. De esa manera, puede omitir el paso 2 por completo.

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

Trampas:

Sin embargo, hay muchas cosas que no están cubiertas en el código anterior. El código anterior no es nulo-seguro.

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

Ahora funciona bien para la mayoría de los valores. Sin embargo, los enteros tienen un rango muy pequeño (valor mínimo / máximo) en comparación con a Double. Además de eso, los dobles también pueden contener "valores especiales", que los enteros no pueden:

  • 1/0 = + infinito
  • -1/0 = -infinito
  • 0/0 = indefinido (NaN)

Por lo tanto, dependiendo de la aplicación, es posible que desee agregar algo de filtrado para evitar Excepciones desagradables.

Entonces, la siguiente deficiencia es la estrategia de redondeo. Por defecto, Java siempre se redondeará hacia abajo. Redondear tiene sentido en todos los lenguajes de programación. Básicamente, Java está tirando algunos de los bytes. En las aplicaciones financieras seguramente querrá usar el redondeo a medias (por ejemplo: round(0.5) = 1y 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) boxeo

Podría estar tentado a usar auto- (un) boxeo en esto, pero no lo haría. Si ya está atrapado ahora, entonces los siguientes ejemplos tampoco serán tan obvios. Si no comprende el funcionamiento interno del auto- (des) boxeo, no lo use.

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)

Supongo que lo siguiente no debería ser una sorpresa. Pero si es así, es posible que desee leer algún artículo sobre cómo transmitir contenido en Java.

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

Valor preferido de:

Además, no se sienta tentado a usar el new Integer()constructor (como lo proponen algunas otras respuestas). Los valueOf()métodos son mejores porque usan el almacenamiento en caché. Es una buena costumbre usar estos métodos, porque de vez en cuando le ahorrarán algo de memoria.

long rounded = (myDouble == null)? 0L: Math.round(myDouble.doubleValue());
Integer val = new Integer(rounded); // waste of memory
bvdb
fuente
1
esta es, en mi opinión, la mejor respuesta
Thor
39

Veo tres posibilidades. Los dos primeros cortan los dígitos, el último se redondea al número entero más cercano.

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
squit
fuente
21
No es necesario el Integer.valueOf si va a almacenar el resultado en un primitieve int. Su código obliga a Java a realizar un cuadro y unbox innecesarios.
bvdb
23

Me gusta esto:

Double foo = 123.456;
Integer bar = foo.intValue();
Richard Schwartz
fuente
23

De hecho, la forma más sencilla es usar intValue(). Sin embargo, esto simplemente devuelve la parte entera; No hace ningún redondeo. Si desea el número entero más cercano al valor doble, deberá hacer esto:

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

Y no olvide el caso nulo:

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

Math.round() maneja casos extraños de pato, como infinito y NaN, con relativa gracia.

Michael Scheper
fuente
2
¿Por qué necesitas Integer.valueOf si lanzas el resultado Math.round a int?
Eran H.
@EranH .: A partir de Java 1.5, probablemente no: el autoboxing significa que el código probablemente termina haciendo lo mismo de cualquier manera. Pero creo que este código es más claro para las personas que aún no han captado los objetos y las primitivas.
Michael Scheper el
Quien haya rechazado esta respuesta: ayudará a la comunidad mucho más si explica por qué, e incluso podría ayudarlo a descubrir por qué no funcionó para usted. El voto negativo sin explicación, OTOH, no es útil para todos, y parece cobarde.
Michael Scheper
14
double a = 13.34;
int b = (int) a;

System.out.println(b); //prints 13
conflittimat
fuente
2
La pregunta era específicamente sobre las clases de envoltura. Esta respuesta es sobre primitivas.
Michael Scheper
8

Simplemente hazlo de esta manera ...

Double d = 13.5578;
int i = d.intValue();
System.out.println(i);
Sunil Sharma
fuente
7
Double d = 100.00;
Integer i = d.intValue();

También se debe agregar que funciona con autoboxing.

De lo contrario, obtienes un int (primitivo) y luego puedes obtener un Integer desde allí:

Integer i = new Integer(d.intValue());
manocha_ak
fuente
2
No use new Integer(int), en su lugar use Integer.valueOf(int), que tiene un caché para enteros pequeños, como este.
bvdb
6

Llama intValue()a tu Doubleobjeto.

Alejandro Pablo Tkachuk
fuente
1
Parece una repetición de las respuestas anteriores.
Pang
4

Puede hacerlo mediante el uso de "Conversión de tipo estrecha o explícita", doble → largo → int. Espero que funcione.

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

PD: Dará 0 ya que el doble tiene todos los valores decimales y nada en el lado izquierdo. En el caso de 0.58, lo reducirá a 0. Pero para otros hará la magia.

Sarthak Bhatia
fuente
4

Prueba este

double doubleValue = 6.5;Double doubleObj = new Double(doubleValue);int intResult = doubleObj.intValue();
Samantha de Silva
fuente
3

Double e Integer son clases de contenedor para primitivas Java para double e int respectivamente. Puedes lanzar entre esos, pero perderás el punto flotante. Es decir, 5.4 lanzado a un int será 5. Si lo devuelve, será 5.0.

OnResolve
fuente
0

Simplemente use el método intValue de Double

Double initialValue = 7.12;
int finalValue = initialValue.intValue();
ravi ranjan
fuente
2
Parece una repetición de las otras respuestas.
Pang
0

Usa el doubleNumber.intValue();método.

PanTau
fuente
2
Parece una repetición de las otras respuestas.
Pang
-1

Memoria eficiente, ya que compartirá la instancia ya creada de Double.

Double.valueOf(Math.floor(54644546464/60*60*24*365)).intValue()
Ravinder Payal
fuente
¿Hay alguna razón para el Math.floor(...)? intValue()Siempre pisos de todos modos.
bvdb
-2

Me ha funcionado. Prueba esto:

double od = Double.parseDouble("1.15");
int oi = (int) od;
Andrey Lychok Lychov-Podvala
fuente