Cast Double en entier en Java


348

Est-il possible de lancer un casting java.lang.Doublesur java.lang.Integer?

Il jette une exception

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

Réponses:


464

A Doublen'est pas un Integer, donc le casting ne fonctionnera pas. Notez la différence entre la Double classe et la double primitive . Notez également que a Doubleest un Number, il a donc la méthode intValue que vous pouvez utiliser pour obtenir la valeur en tant que primitive int.


2
Ok pour ne pas lancer. J'ai besoin d'obtenir un objet Integer de Double, pas 13.22222 mais 13, par exemple.
4lex1v

181
appelez intValue()alors.
hvgotcodes

6
N'oubliez pas de gérer les valeurs nulles.
pimlottc

13
Notez que cela renvoie simplement la partie entière du Double, donc pour 13.666667 ou même 13.9, vous obtiendrez 13, pas 14. Si vous voulez l' entier le plus proche , référez-vous à ma réponse: stackoverflow.com/a/24816336/1450294
Michael Scheper

2
si vous regardez l'implémentation de intValue(), cela transforme simplement le doubleen an int.
carlo.marinangeli

566

Vous devez obtenir explicitement la valeur int en utilisant la méthode intValue () comme ceci:

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

Ou

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

67
Je vous remercie. Très clair. La réponse acceptée, pour moi, ressemble à une réprimande pour avoir posé une question idiote. Mais votre réponse est très généreuse.
Buddhika Ariyaratne du

2
Que se passe-t-il lorsque la valeur double est en dehors de la plage entière? (comme 2 ^ 33)
nikdeapen

5
Toute valeur double> 2^31 - 1 (Integer.MAX_VALUE)débordera.
anubhava

3
Et, en passant, lorsqu'il est converti de double en entier, il ne conserve que la partie entière, pour les nombres positifs et négatifs, et ne se soucie pas de l'arrondi. par exemple 1.6 -> 1, 1.4 -> 1, -1.6 -> -1, -1.4 -> -1,
Eric Wang

51

Je pense qu'il est impossible de comprendre les autres réponses sans couvrir les pièges et raisonner derrière.

Vous ne pouvez pas directement convertir Integerun Doubleobjet en objet. Aussi Doubleet Integersont des objets immuables, vous ne pouvez donc pas les modifier en aucune façon.

Chaque classe numérique a une alternative primitive ( Doublevs double, Integervs int, ...). Notez que ces primitives commencent par un caractère minuscule (par exemple int). Cela nous dit qu'ils ne sont pas des classes / objets. Ce qui signifie également qu'ils n'ont pas de méthodes. En revanche, les classes (par exemple Integer) agissent comme des boîtes / wrappers autour de ces primitives, ce qui permet de les utiliser comme des objets.

Stratégie:

Pour convertir un Doubleen un, Integervous devez suivre cette stratégie:

  1. Convertissez l' Doubleobjet en primitive double. (= "déballage")
  2. Convertissez la primitive doubleen primitive int. (= "casting")
  3. Convertissez la primitive inten Integerobjet. (= "boxe")

Dans du code:

// 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 fait, il y a un raccourci. Vous pouvez décompresser immédiatement d'une Doubleligne droite à une primitive int. De cette façon, vous pouvez ignorer complètement l'étape 2.

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

Pièges:

Cependant, il y a beaucoup de choses qui ne sont pas couvertes dans le code ci-dessus. Le code ci-dessus n'est pas null-safe.

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

Maintenant, cela fonctionne bien pour la plupart des valeurs. Cependant, les entiers ont une très petite plage (valeur min / max) par rapport à a Double. En plus de cela, les doubles peuvent également contenir des "valeurs spéciales", que les entiers ne peuvent pas:

  • 1/0 = + infini
  • -1/0 = -infinity
  • 0/0 = non défini (NaN)

Ainsi, selon l'application, vous souhaiterez peut-être ajouter un filtrage pour éviter les exceptions désagréables.

Ensuite, la prochaine lacune est la stratégie d'arrondi. Par défaut, Java arrondira toujours vers le bas. L'arrondi est parfaitement logique dans tous les langages de programmation. Fondamentalement, Java jette simplement certains des octets. Dans les applications financières, vous voudrez sûrement utiliser l'arrondissement de moitié (par exemple: round(0.5) = 1et round(0.4) = 0).

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

Boxe (dé) automatique

Vous pourriez être tenté d'utiliser la boxe (dé) automatique , mais je ne le ferais pas. Si vous êtes déjà coincé maintenant, les exemples suivants ne seront pas aussi évidents. Si vous ne comprenez pas le fonctionnement interne de la (dé) boxe automatique, alors ne l'utilisez pas.

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)

Je suppose que ce qui suit ne devrait pas être une surprise. Mais si c'est le cas, vous voudrez peut-être lire un article sur la diffusion en Java.

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

Préférez valueOf:

Aussi, ne soyez pas tenté d'utiliser le new Integer()constructeur (comme le proposent d'autres réponses). Les valueOf()méthodes sont meilleures car elles utilisent la mise en cache. C'est une bonne habitude d'utiliser ces méthodes, car de temps en temps, elles vous feront économiser de la mémoire.

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

1
c'est à mon avis la meilleure réponse
Thor

39

Je vois trois possibilités. Les deux premiers coupent les chiffres, le dernier arrondit à l'entier le plus proche.

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
Il n'y a pas besoin de Integer.valueOf si vous allez stocker le résultat dans un primitieve int. Votre code oblige Java à effectuer une boîte et un déballage inutiles.
bvdb


23

En effet, la manière la plus simple est d'utiliser intValue(). Cependant, cela renvoie simplement la partie entière; il ne fait aucun arrondi. Si vous voulez que l'entier soit le plus proche de la valeur Double, vous devrez le faire:

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

Et n'oubliez pas le cas nul:

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

Math.round() gère les cas de canard impairs, comme l'infini et NaN, avec une grâce relative.


2
Pourquoi avez-vous besoin d'Integer.valueOf si vous convertissez le résultat Math.round en entier?
Eran

@EranH .: À partir de Java 1.5, vous ne le faites probablement pas - l'autoboxing signifie que le code finira probablement par faire la même chose de toute façon. Mais je pense que ce code est plus clair pour les personnes qui n'ont pas encore tout à fait saisi les objets et les primitives.
Michael Scheper

Celui qui a voté contre cette réponse: vous aiderez beaucoup plus la communauté si vous expliquez pourquoi, et cela pourrait même vous aider à découvrir pourquoi cela n'a pas fonctionné pour vous. Le vote négatif sans explication, OTOH, est inutile pour tout le monde, et il semble lâche.
Michael Scheper

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

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

2
La question portait spécifiquement sur les classes wrapper. Cette réponse concerne les primitives.
Michael Scheper

8

Faites-le simplement de cette façon ...

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

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

Il faut également ajouter que cela fonctionne avec la boîte automatique.

Sinon, vous obtenez un int (primitif), puis vous pouvez obtenir un entier à partir de là:

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

2
N'utilisez pas, utilisez new Integer(int)plutôt Integer.valueOf(int), qui a un cache pour les petits entiers, comme celui-ci.
bvdb


4

Vous pouvez le faire en utilisant "Conversion de type étroite ou explicite", double → long → int. J'espère que ça marchera.

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

PS: Il donnera 0 car le double a toutes les valeurs décimales et rien sur le côté gauche. Dans le cas de 0,58, il le réduira à 0. Mais pour d'autres, il fera la magie.


4

Essaye celui-là

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

3

Double et Integer sont des classes wrapper pour les primitives Java pour double et int respectivement. Vous pouvez lancer entre ceux-ci, mais vous perdrez la virgule flottante. C'est-à-dire que 5.4 converti en entier sera 5. Si vous le restituez, ce sera 5.0.


0

Utilisez simplement la méthode intValue de Double

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

2
On dirait une répétition des autres réponses.
Pang

0

Utilisez la doubleNumber.intValue();méthode.


2
On dirait une répétition des autres réponses.
Pang

-1

Mémoire efficace, car elle partagera l'instance déjà créée de Double.

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

Y a-t-il une raison à cela Math.floor(...)? intValue()toujours des planchers de toute façon.
bvdb

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.