2010-12-13 21 views
19

Ho interi che dovrebbero essere uguali (e lo verifichi in base all'output). Ma nella mia condizione if, Java non vede queste variabili avere lo stesso valore.Perché Java non vede che i numeri interi sono uguali?

ho il seguente codice:

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

Ed produrre il seguente output:

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

Probabilmente devo aggiungere che point è definito così:

Integer[] point = new Integer[2]; 

e pay presi dal costruttore di loop:

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

Quindi, queste due variabili hanno entrambi il tipo intero.

+3

se hai una mente aperta, allora si può come la mia spiegazione ... È perché i creatori di Java regalmente avvitato su quando hanno deciso di fare le classi wrapper, che hanno prestazioni veramente patetico (non hai idea dello spreco generato dal wrapping di un * int * all'interno di un * Integer *). Lo hanno fatto principalmente perché non erano in grado di progettare qualcosa di pulito ed efficiente come, ad esempio, * Trove * 's * TLongIntHashMap *. Naturalmente aspettatevi commenti da parte di persone che hanno bevuto il raffreddatore Java spiegando come ho sbagliato e come le classi wrapper sono una manna dal cielo;) – SyntaxT3rr0r

+1

btw, mai e poi mai fare un * nuovo Integer [2] * perché forzate il creazione di un nuovo oggetto. ** IFF ** continui a utilizzare classi wrapper come * Integer * (che in realtà non dovresti ma è un altro argomento), vuoi fare un * Integer.valueOf (2) * (btw che successivamente ** garantisce ** secondo le specifiche Java, il riutilizzo dei primi 256 oggetti interi da -128 a 127, ma non è un brainfart Java molto noto). – SyntaxT3rr0r

+0

SpoonBender: Che dire della decisione dei creatori di Java di * solo * consentire l'overloading dell'operatore per le stringhe? In questo modo 'Integer.valueOf (127) == Integer.valueOf (127)' but 'Integer.valueOf (128)! = Integer.valueOf (128)'! – Gabe

risposta

49

oggetti (come Integer s) non devono essere confrontati con ==, ma attraverso .equals().

Ciò che è importante capire è che diversi oggetti Integer diversi possono rappresentare lo stesso valore int. Quando il tuo programma stampa >>> different, dice semplicemente che il primo oggetto non è lo stesso oggetto come secondo oggetto. (Mentre probabilmente si desidera confrontare gli oggetti in base al quale il valore che rappresentano.)

Dal official guide su autoboxing:

[...] L'operatore == esegue confronti identità di riferimento sulle espressioni Integer e confrontare i confronti di uguaglianza sulle espressioni int. [...]

Può essere interessante notare che autoboxing è garantito per restituire lo stesso oggetto per valori interi nell'intervallo [-128, 127], ma un'implementazione può, a sua discrezione, valori di cache al di fuori di tale intervallo.

La mia raccomandazione generale è quella di utilizzare int anziché Integer per tutte le variabili locali/membro. In questo caso particolare, sembra che memorizzi le coordinate in un array a 2 elementi. Ti suggerisco di incapsularlo in una classe Coordinates o simile e sostituire qui il metodo equals (e hashCode).

Vedi anche

9

Se fossero semplici int tipi, che avrebbe funzionato.

Per Integer utilizzare .intValue() o compareTo(Object other) o equals(Object other) nel confronto.

4

Ci sono due tipi di distinguere qui:

  • int, il tipo intero primitiva che si utilizza la maggior parte del tempo, ma non è un tipo di oggetto
  • Integer, un involucro oggetto attorno ad un int che può essere utilizzato per utilizzare numeri interi in API che richiedono oggetti
1

quando si tenta di confrontare due oggetti (e un intero è un oggetto, non una variabile) il risultato sarà sempre che t hey're non uguale,

nel tuo caso si dovrebbe confrontare i campi degli oggetti (in questo caso intValue)

provare dichiarando variabili int al posto di oggetti Integer, vi aiuterà

2

In valori numerici Java entro il raggio di -128 a 127 vengono memorizzati nella cache, quindi se si tenta di confrontare

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

questo funzionerebbe, ma se si prova con i numeri di fuori del campo danno sopra hanno bisogno di essere confrontato con metodo equals per il confronto valore perché "==" controllerà se entrambi sono lo stesso oggetto non lo stesso valore.

0

La condizione in

pay[0]==point[0] 

espressione, utilizza l'operatore uguaglianza == per confrontare un riferimento

Integer pay[0] 

per uguaglianza con il riferimento

Integer point[0] 

In generale, quando i valori di tipo primitivo (come int, ...) sono confrontati con ==, il risultato è vero se entrambi i valori sono identici. Quando i riferimenti (come Integer, String, ...) vengono confrontati con ==, il risultato è true se entrambi i riferimenti si riferiscono allo stesso oggetto in memoria. Per confrontare i contenuti effettivi (o le informazioni sullo stato) degli oggetti per l'uguaglianza, è necessario richiamare un metodo. Così, con questo

Integer[] point = new Integer[2]; 

espressione si crea un nuovo oggetto che ha avuto nuovo riferimento e assegnarlo a punto variabile.

Ad esempio:

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

per confrontare una con l'uso b:

a == b 

perché entrambi sono valori primitivi tipo.

per confrontare una con l'uso c:

a == c 

a causa della funzione di auto-boxing.

per confrontare c con e uso:

c.equals(e) 

a causa della nuova referenza in e variabile.

per confrontare c con d è migliore e sicuro da usare:

c.equals(d) 

a causa di:

Come sapete, l'operatore ==, applicato in oggetti wrapper, solo verifica se gli oggetti hanno posizioni di memoria identiche. Il seguente confronto sarebbe quindi probabilmente fallirà:

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

Tuttavia, un'implementazione Java può, se lo desidera, avvolgere i valori che si verificano comunemente in oggetti identici, e quindi il confronto potrebbe avere successo. Questa ambiguità non è ciò che vuoi. Il rimedio è chiamare il metodo equals quando si confrontano gli oggetti wrapper.

Problemi correlati