Domanda
Ogni volta che utilizzo il metodo equals () con due diversi oggetti StringBuffer, ottengo il risultato come falso, ma quando uso il metodo equals () con due diversi oggetti String, ottengo il risultato come vero. Perché?
String s=new String("434");
String s1=new String("434");
System.out.println(s.equals(s1));//true
StringBuffer s=new StringBuffer("434");
StringBuffer s1=new StringBuffer("434");
System.out.println(s.equals(s1));//false
Soluzione
StringBuffer non sovrascrive equals (). Come tale, viene chiamato Object.equals (), che confronta l'identità dell'oggetto (l'indirizzo di memoria). String sostituisce uguale e confronta il contenuto.
Altri suggerimenti
StringBuffer
non sostituisce Object # equals ()
, quindi si verificano controlli basati su identità di riferimento anziché valore controlli basati su . Poiché queste istanze StringBuilder
sono distinte, ognuna con posizioni di memoria diverse, l'implementazione di base Object # equals ()
restituirà sempre false.
Ecco la definizione di Java 6:
public boolean equals(Object obj) {
return (this == obj);
}
Vedi il problema?
Almeno nella mia versione di JDK (Sun 1.6), StringBuffer non implementa un metodo equals (). Ciò significa che eredita il metodo equals () di Object, che è uguale a ==
Se vuoi davvero testare due StringBuffer per l'uguaglianza, puoi chiamare x.toString (). equals (y.toString ())
Se quello che stai cercando di fare è confrontare le rappresentazioni String dei due oggetti StringBuffer, allora quello che vuoi fare è:
StringBuffer sb1 = new StringBuffer("434");
StringBuffer sb2 = new StringBuffer("434");
if (sb1.toString().equals(sb2.toString())) {
// whatever you want to do if they're equal
} else {
// whatever you want to do if they're not
}
Altrimenti, stai confrontando per l'uguaglianza dei due StringBuffer oggetti , non per il loro contenuto - in altre parole, eseguendo Object # equals (), non (l'inesistente) StringBuffer # equals ().
uguale a restituisce true solo sugli oggetti StringBuffer quando i due oggetti sono uguali. Per confrontare StringBuffer nel modo desiderato, utilizzare questo:
System.out.println(s.toString().equals(s1.toString());
String s.equals utilizzerà la tabella delle stringhe per confrontare le stringhe effettive, mentre StringBuffer sb.equals utilizzerà l'implementazione predefinita del metodo equals e confronterà solo i puntatori oggetto.
StringBuffer non ha la propria implementazione del metodo equals ma eredita il metodo equals () dalla classe di oggetti, quindi gli hashvalues ??vengono confrontati piuttosto che confrontare il contenuto effettivo in stringBuffer. Quindi dobbiamo esplicitamente lanciarlo su un oggetto stringa che fornisce l'implementazione per il metodo equals ().
La semantica dell'oggetto String
è tale che se si osserva che due istanze contengono la stessa sequenza di caratteri, conterranno sempre la stessa sequenza di caratteri e si potrebbe - almeno da il punto di vista dell'oggetto String
stesso - sostituisce tutti i riferimenti a una delle stringhe con riferimenti all'altra senza cambiare la semantica del programma. Tali istanze possono essere considerate equivalenti, poiché per tutti gli scopi pratici, l'unica informazione incapsulata in un'istanza di String
è la sequenza di caratteri contenuta nell'istanza target.
Al contrario, una variabile di tipo StringBuffer
incapsula non solo una sequenza di caratteri, ma anche la identità di un'istanza particolare . Se due variabili si riferiscono alla stessa istanza, la modifica all'istanza a cui fa riferimento una variabile influirà sull'istanza a cui fa riferimento l'altra (poiché si tratta della stessa istanza). Se si riferiscono a istanze diverse, le modifiche all'istanza a cui fa riferimento uno non influiranno sull'istanza a cui fa riferimento l'altro. La decisione di non far sovrascrivere StringBuffer
di Java equals
non è stata una conseguenza della pigrizia, ma era piuttosto basata sul fatto che gli oggetti StringBuffer
hanno un identità significativa e istanze disgiunte hanno sempre identità diverse.