web-dev-qa-db-fra.com

Pourquoi Java ne voit pas que les entiers sont égaux?

J'ai des entiers qui sont supposés être égaux (et je le vérifie par la sortie). Mais dans ma condition if, Java ne voit pas ces variables avoir la même valeur.

J'ai le code suivant:

if (pay[0]==point[0] && pay[1]==point[1]) {
    game.log.fine(">>>>>> the same");
} else {
    game.log.fine(">>>>>> different");
}
game.log.fine("Compare:" + pay[0] + "," + pay[1] + " -> " + point[0] + "," + point[1]);

Et cela produit la sortie suivante:

FINE: >>>>>> different
FINE: Compare:: 60,145 -> 60,145

Je dois probablement ajouter que point est défini comme ceci:

Integer[] point = new Integer[2];

et pay nous avons pris du constructeur de boucle:

for (Integer[] pay : payoffs2exchanges.keySet())

Donc, ces deux variables ont le type entier.

21
Roman

Les objets (tels que Integers) ne doivent pas être comparés avec ==, mais avec .equals().

Il est important de comprendre que plusieurs objets Integer différents peuvent représenter la même valeur int. Lorsque votre programme imprime >>> different, il indique simplement que le premier objet n'est pas le même objet que le deuxième objet. (Bien que vous souhaitiez probablement comparer les objets en fonction de la valeur qu’ils représentent.)

Du guide officiel sur l'autoboxing:

[...] L'opérateur == effectue des comparaisons d'identité de référence sur les expressions Integer et des comparaisons d'égalité de valeurs sur les expressions int. [...]

Il peut être intéressant de noter que le retour automatique au même objet est garanti pour les valeurs intégrales comprises dans la plage [-128, 127], mais une implémentation peut, à sa discrétion, mettre en cache des valeurs en dehors de cette plage.

Ma recommandation générale est d'utiliser int au lieu de Integer pour toutes les variables locales/membres. Dans ce cas particulier, vous semblez stocker les coordonnées dans un tableau à 2 éléments. Je suggérerais que vous encapsuliez ceci dans une classe Coordinates ou similaire et que vous surchargiez la méthode equals (et hashCode) ici.

Voir également

54
aioobe

S'il s'agissait de types int simples, cela fonctionnerait.

Pour Integer, utilisez .intValue() ou compareTo(Object other) ou equals(Object other) dans votre comparaison.

11
sje397

Il y a deux types à distinguer ici:

  • int, le type entier primitif que vous utilisez la plupart du temps, mais qui n'est pas un type d'objet
  • Integer, un wrapper d'objet autour d'une int qui peut être utilisé pour utiliser des entiers dans les API nécessitant des objets
4
Bart van Heukelom

En Java, les valeurs numériques comprises entre -128 et 127 sont mises en cache. Par conséquent, si vous essayez de comparer

Integer i=12 ;
Integer j=12 ; // j is pointing to same object as i do.
if(i==j)
   print "true";

cela fonctionnerait, mais si vous essayez avec des nombres en dehors de la plage ci-dessus, vous devez les comparer avec la méthode égal à la comparaison des valeurs, car "==" vérifiera si les deux sont le même objet et non la même valeur.

2
Nayan Srivastava

lorsque vous essayez de comparer deux objets (et un entier est un objet, pas une variable), le résultat sera toujours qu'ils ne sont pas égaux,

dans votre cas, vous devez comparer les champs des objets (dans ce cas, intValue)

essayez de déclarer des variables int au lieu d'objets Integer, cela vous aidera

1
Andrzej Bobak

La condition à

pay[0]==point[0]

expression, utilise l'opérateur d'égalité == pour comparer une référence

Integer pay[0]

pour l'égalité avec la référence

Integer point[0]

En général, lorsque les valeurs de type primitif (telles que int, ...) sont comparées à ==, le résultat est vrai si les deux valeurs sont identiques. Lorsque des références (telles que Integer, String, ...) sont comparées à ==, le résultat est vrai si les deux références font référence au même objet en mémoire. Pour comparer le contenu réel (ou les informations d'état) des objets à des fins d'égalité, une méthode doit être appelée. Ainsi, avec cette

Integer[] point = new Integer[2];

expression vous créez un nouvel objet avec une nouvelle référence et l’affectez à une variable ponctuelle.

Par exemple:

int a = 1;
int b = 1;
Integer c = 1;
Integer d = 1;
Integer e = new Integer(1);

Pour comparer a avec b utiliser:

a == b

parce que les deux sont des valeurs de type primitif.

Pour comparer une utilisation avec c:

a == c

en raison de la fonctionnalité de boxe automatique.

pour comparer c avec e utilisation:

c.equals(e)

en raison de la nouvelle référence dans la variable e.

pour comparer c avec d, il est préférable et sûr d’utiliser:

  c.equals(d)

en raison de:

Comme vous le savez, l'opérateur ==, appliqué aux objets wrapper, vérifie uniquement si les objets ont des emplacements mémoire identiques. La comparaison suivante échouerait donc probablement:

Integer a = 1000;
Integer b = 1000;
if (a == b) . . .

Toutefois, une implémentation Java peut, si elle le souhaite, englober des valeurs courantes dans des objets identiques et, par conséquent, la comparaison peut aboutir. Cette ambiguïté n'est pas ce que vous voulez. Le remède consiste à appeler la méthode equals lors de la comparaison d'objets wrapper.

0
MMKarami