2010-12-13 9 views
19

Ich habe Integer, die gleich sein sollen (und ich verifiziere es durch Ausgabe). Aber in meiner if Bedingung erkennt Java nicht, dass diese Variablen den gleichen Wert haben.Warum Java nicht sieht, dass Ganzzahlen gleich sind?

Ich habe den folgenden Code:

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

Und es erzeugen die folgende Ausgabe:

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

Wahrscheinlich muss ich hinzufügen, dass point so definiert:

Integer[] point = new Integer[2]; 

und pay uns aus dem Schleifenkonstruktor genommen:

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

Also, diese beiden Variablen haben beide den Integer-Typ.

+3

, wenn Sie einen offenen Geist haben, dann können Sie meine Erklärung mag ... Es ist, weil die Java Schöpfer fürstlich geschraubt, wenn sie die Wrapper-Klassen machen beschlossen, die wirklich erbärmlich Leistung haben (Sie nicht haben Idee über den Abfall, der durch das Umschließen eines * int * innerhalb eines * Integer *) erzeugt wird. Sie taten das hauptsächlich, weil sie nicht in der Lage waren, etwas sauberes und effizientes zu gestalten, wie zum Beispiel * Troves * s * TLongIntHashMap *. Natürlich erwarten snarky kniejerk upvoted Kommentare hier von Leuten, die die Java Cool-Hilfe getrunken haben und erklären, wie ich falsch liege und wie Wrapperklassen ein Glücksfall sind;) – SyntaxT3rr0r

+1

BTW, mach niemals ein * neues Integer [2] * weil du das erzwingst Erstellung eines neuen Objekts. ** IFF ** Du verwendest immer Wrapper-Klassen wie * Integer * (das solltest du eigentlich nicht, aber das ist ein anderes Thema), du willst ein * Integer.valueOf (2) * machen (was später ** garantiert **) Laut den Java-Spezifikationen die Wiederverwendung der ersten 256 Integer-Objekte von -128 bis 127, aber das ist kein sehr bekannter Java-Brainfart. – SyntaxT3rr0r

+0

SpoonBender: Was ist mit der Entscheidung der Java-Ersteller * nur * dem Operator das Überladen von Strings zu erlauben? Auf diese Weise 'Integer.valueOf (127) == Integer.valueOf (127)' aber 'Integer.valueOf (128)! = Integer.valueOf (128)'! – Gabe

Antwort

49

Objekte (wie Integer s) sollten nicht über ==, sondern über .equals() verglichen werden.

Es ist wichtig zu verstehen, dass mehrere verschiedene Integer Objekte den gleichen int-Wert darstellen können. Wenn Ihr Programm >>> different druckt, sagt es einfach, dass das erste Objekt nicht dasselbe Objekt als das zweite Objekt ist. (Während Sie wahrscheinlich die Objekte vergleichen wollen, basierend auf welchen Wert sie darstellen.)

Vom official guide auf Autoboxing:

[...] Der Operator == führt Vergleiche Referenz Identität auf Integer Ausdrücke und Gleichheitsvergleiche für int-Ausdrücke. [...]

Es kann sich lohnen, unter Hinweis darauf, dass Autoboxing ist garantiert das gleiche Objekt für ganzzahlige Werte im Bereich zurückzukehren [-128, 127], sondern eine Umsetzung kann nach eigenem Ermessen, Cache-Werte außerhalb dieses Bereichs.

Meine allgemeine Empfehlung ist int anstelle von Integer für alle lokalen/Member-Variablen zu verwenden. In diesem speziellen Fall scheinen Sie Koordinaten in einem 2-Element-Array zu speichern. Ich würde vorschlagen, dass Sie dies in einer Klasse Coordinates oder ähnlich kapseln und überschreiben die equals-Methode (und hashCode) hier.

Siehe

9

auch wenn sie int Typen einfach wäre, würde es funktionieren.

Für Integer verwenden Sie .intValue() oder compareTo(Object other) oder equals(Object other) in Ihrem Vergleich.

4

Es gibt zwei Arten hier zu unterscheiden:

  • int, den primitiven Integer-Typen, die Sie die meiste Zeit verwenden, aber es ist nicht ein Objekttyp
  • Integer, ein Objekt-Wrapper um ein int die kann verwendet werden, ganze Zahlen in APIs zu verwenden, die
1

Objekte benötigen, wenn Sie versuchen, zwei Objekte zu vergleichen (und eine ganze Zahl ist ein Objekt, keine Variable) wird das Ergebnis immer, dass t sein hey're nicht gleich,

in Ihrem Fall sollten Sie Felder der Objekte vergleichen (in diesem Fall intValue)

versuchen int Variablen statt Integer-Objekte deklarieren, wird es

2

in Java numerische Werte helfen innerhalb des Bereichs von -128 bis 127 zwischengespeichert werden, so, wenn Sie versuchen,

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

dies funktionieren würde zu vergleichen, aber wenn man mit Zahlen aus dem oben geben Bereich versuchen müssen sie verglichen werden mit Verfahren zum Wertvergleich entspricht, weil "==" überprüft beide sind das gleiche Objekt nicht der gleiche Wert.

0

Der Zustand bei

pay[0]==point[0] 

Ausdruck, verwendet das Gleichheitsoperator == einen Verweis mit der einer Referenz

Integer point[0] 

Im Allgemeinen

Integer pay[0] 

auf Gleichheit zu vergleichen, wenn primitive-type-Werte (wie int, ...) werden mit == verglichen, das Ergebnis ist wahr, wenn beide Werte identisch sind. Wenn Verweise (wie Integer, String, ...) mit == verglichen werden, ist das Ergebnis wahr, wenn sich beide Verweise auf dasselbe Objekt im Speicher beziehen. Um den tatsächlichen Inhalt (oder Zustandsinformationen) von Objekten auf Gleichheit zu vergleichen, muss eine Methode aufgerufen werden. So , mit diesem

Integer[] point = new Integer[2]; 

Ausdruck erstellen Sie ein neues Objekt, das neue Referenz bekommen hat, und weisen Sie Variable zu verweisen.

Zum Beispiel:

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

Um einen Vergleich mit b Verwendung:

a == b 

weil beide primitive-Typ Werte sind.

a == c 

wegen Auto-Box Funktion:

Um ein mit c Verwendung zu vergleichen.

für vergleichen c mit e Verwendung:

c.equals(e) 

wegen der neuen Referenz in e-Variable.

für vergleichen c mit d es ist besser und sicher zu bedienen:

c.equals(d) 

wegen:

Wie Sie wissen, ist der Operator ==, angewendet Objekte Wrapper, nur prüft, ob Die Objekte haben identische Speicherplätze. Der folgende Vergleich wäre daher wahrscheinlich fehlschlagen:

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

jedoch eine Java-Implementierung kann, wenn es wählt, wickeln häufig Werte in identische Objekte auftreten, und somit könnte der Vergleich erfolgreich zu sein. Diese Mehrdeutigkeit ist nicht das, was Sie wollen. Abhilfe besteht darin, beim Vergleich von Wrapper-Objekten die Methode equals aufzurufen.

Verwandte Themen