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"

4lex1v
la source

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.

hvgotcodes
la source
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;
anubhava
la source
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
bvdb
la source
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
squit
la source
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

Comme ça:

Double foo = 123.456;
Integer bar = foo.intValue();
Richard Schwartz
la source
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.

Michael Scheper
la source
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
conflittimat
la source
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);
Sunil Sharma
la source
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());
manocha_ak
la source
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
6

intValue()Faites appel à votre Doubleobjet.

Alejandro Pablo Tkachuk
la source
1
Cela ressemble à une répétition des réponses précédentes.
Pang
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.

Sarthak Bhatia
la source
4

Essaye celui-là

double doubleValue = 6.5;Double doubleObj = new Double(doubleValue);int intResult = doubleObj.intValue();
Samantha de Silva
la source
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.

OnResolve
la source
0

Utilisez simplement la méthode intValue de Double

Double initialValue = 7.12;
int finalValue = initialValue.intValue();
ravi ranjan
la source
2
On dirait une répétition des autres réponses.
Pang
0

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

PanTau
la source
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()
Ravinder Payal
la source
Y a-t-il une raison à cela Math.floor(...)? intValue()toujours des planchers de toute façon.
bvdb
-2

Ça a marché pour moi. Essaye ça:

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