Qual è la differenza tra il String#equals
metodo e il String#contentEquals
metodo?
Qual è la differenza tra il String#equals
metodo e il String#contentEquals
metodo?
Risposte:
Il String#equals()
non solo confronta il contenuto della stringa, ma controlla anche se l'altro oggetto è anche un'istanza di a String
. L' String#contentEquals()
unico confronta i contenuti (la sequenza di caratteri) e non controlla se l'altro oggetto è anche un'istanza di String
. Può essere qualsiasi cosa, purché si tratta di un'implementazione di CharSequence
che copre AO String
, StringBuilder
, StringBuffer
, CharBuffer
, etc.
==
operatore ti consentirà solo di confrontare i riferimenti e non il contenuto di due oggetti.
==
citato è solo JavaScript; non è mai stato menzionato per quanto riguarda Java.
==
in JavaScript è molto più sciolto di contentEquals
, che non toccherà i numeri, per esempio), ma hai ragione nel equals
verificare la corrispondenza esatta del tipo conStrings
(altre classi potrebbero essere più libere con i tipi nei loro equals
metodi) .
Per dirla facilmente: String.contentEquals()
è il fratello più intelligente di String.equals()
, perché può essere più libero nell'implementazione che String.equals()
.
Ci sono alcuni motivi per cui esiste un String.contentEquals()
metodo separato . Il motivo più importante che penso è:
equals
metodo deve essere riflessivo. Ciò significa che: x.equals(y) == y.equals(x)
. Ciò implica che aString.equals(aStringBuffer)
dovrebbe essere lo stesso di aStringBuffer.equals(aString)
. Ciò richiederebbe agli sviluppatori dell'API Java di realizzare un'implementazione speciale per Strings anche nel equals()
metodo StringBuffer, StringBuilder e CharSequence. Questo sarebbe un casino.Qui è dove String.contentEquals
entra in gioco. Questo è un metodo di stand-alone che non non deve seguire i severi requisiti e le regole per Object.equals
. In questo modo, puoi implementare il senso di "uguale contenuto" più liberamente. Ciò consente, ad esempio, di effettuare confronti intelligenti tra StringBuffer e String.
E dire qual è esattamente la differenza:
String.contentEquals()
può confrontare i contenuti di a String
, a StringBuilder
, a StringBuffer
, a CharSequence
e tutte le classi derivate di questi. Se il parametro è di tipo String, allora String.equals()
esegui.
String.equals()
confronta solo oggetti String. Tutti gli altri tipi di oggetti sono considerati non uguali.
String.contentEquals()
può confrontare StringBuffer
e StringBuilder
in modo intelligente. Essa non chiamare il pesante toString()
metodo, che copia l'intero contenuto di un nuovo oggetto String. Invece, si confronta con l' char[]
array sottostante , il che è fantastico.
Questa risposta è stata già pubblicata da dbw ma l'ha eliminata ma aveva alcuni punti molto validi per la differenza durante il confronto dei tempi di esecuzione, quali eccezioni vengono generate,
Se guardi il codice sorgente String # equals e String # contentEquals è chiaro che ci sono due metodi sovrascritti per String#contentEquals
uno che accetta StringBuilder
e l'altro CharSequence
.
La differenza tra loro,
String#contentEquals
genererà NPE se l'argomento fornito è null
ma String#equals
restituiràfalse
String#equals
confronta il contenuto solo quando l'argomento fornito è instance of String
altrimenti tornerà false
in tutti gli altri casi ma d'altra parte String#contentEquals
controlla il contenuto di tutti gli oggetti che implementano l'interfaccia CharSequence
.Puoi anche modificare il codice in modo che String#contentEquals
restituisca il risultato o il risultato errato che desideri sostituendo il equals
metodo dell'argomento passato come mostrato di seguito, ma non puoi fare quelle modifiche String#equals
.
Il codice seguente produrrà sempretrue
finché s
contiene string
3 caratteri
String s= new String("abc");// "abc";
System.out.println(s.contentEquals(new CharSequence()
{
@Override
public CharSequence subSequence(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public int length() {
// TODO Auto-generated method stub
return 0;
}
@Override
public char charAt(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean equals(Object obj)
{
return true;
}
}));
String#contentEquals
sarà più lento quindi String#Equals
nel caso in cui l'argomento fornito sia instance of String
e la lunghezza di entrambi String
sia la stessa ma i contenuti non siano uguali.
Esempio se la stringa è String s = "madam"
e String argPassed = "madan"
quindi s.contentEquals(argPassed)
impiegherà quasi il doppio del tempo di esecuzione in questo caso rispetto as.equals(argPassed)
Se la lunghezza del contenuto non è la stessa per entrambe le stringhe, la funzione String#contentEquals
avrà prestazioni migliori rispetto String#Equals
a quasi tutti i casi possibili.
Un altro punto da aggiungere alla sua risposta
String#contentEquals
di un String
oggetto verrà inoltre confrontato con il StringBuilder
contenuto e fornirà il risultato appropriato mentre String#Equals
verrà restituitofalse
String
il equals(Object o)
metodo class fa solo un String
confronto. Ma i contentEquals(CharSequence cs)
controlli per le classi si estendono AbstractStringBuilder
cioè StringBuffer
, StringBuilder
e String
anche la classe (sono tutti di tipo CharSequence
).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
produzione:
false
true
L'uscita del primo stmt è false
perché builder
non è di tipo String
così equals()
rendimenti false
ma i contentEquals()
controlli per il contenuto di tutti del tipo come StringBuilder
, StringBuffer
, String
e il contenuto è lo stesso di conseguenza true
.
contentEquals
verrà generato NullPointerException
se l'argomento fornito è null
ma equals()
restituirà false perché equals () controlla ad esempioOf ( if (anObject instance of String)
) che restituisce false se l'argomento è null
.contentEquals(CharSequence cs)
:
java.lang.CharacterSequence
(ad esempio, CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
:
java.lang.String
soloRTFC :)
Poiché la lettura della fonte è il modo migliore per capirla, condivido le implementazioni di entrambi i metodi (a partire da jdk 1.7.0_45)
public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
char v1[] = value;
char v2[] = ((AbstractStringBuilder) cs).getValue();
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
// Argument is a String
if (cs.equals(this))
return true;
// Argument is a generic CharSequence
char v1[] = value;
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != cs.charAt(i))
return false;
i++;
}
return true;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Esiste un altro metodo di String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()
e contentEquals()
sono due metodi in String
classe per confrontare due strings
e string
con StringBuffer
.
I parametri di contentEquals()
are StringBuffer
e String(charSequence)
. equals()
viene utilizzato per confrontare due strings
e contentEquals()
viene utilizzato per confrontare i contenuti di String
e StringBuffer
.
Metodo contentEquals
e lo equals
sono
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Ecco un codice che descrive entrambi i metodi
public class compareString {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
boolean result1 = str1.equals(str2); // works nice and returns true
System.out.println(" str1.equals(str2) - "+ result1);
boolean result2 = str1.equals(sb1); // works nice and returns false
System.out.println(" str1.equals(sb1) - "+ result2);
boolean result3 = str1.contentEquals(sb1); // works nice and returns true
System.out.println(" str1.contentEquals(sb1) - "+ result3);
boolean result4 = str1.contentEquals(sb2); // works nice and returns false
System.out.println(" str1.contentEquals(sb2) - "+ result4);
boolean result5 = str1.contentEquals(str2); // works nice and returns true
System.out.println(" str1.contentEquals(str2) - "+ result5);
}
}
Produzione:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
String # equals accetta Object come argomento e verifica che sia un'istanza di String object o meno. Se l'oggetto argomento è String Object, confronta il contenuto carattere per carattere. Restituisce vero nel caso in cui il contenuto di entrambi gli oggetti stringa sia uguale.
String # contentEquals utilizza l'interfaccia CharSequence come argomento. CharSequence può essere implementato in 2 modi: utilizzando i) Classe String o (ii) AbstractStringBuilder (classe padre di StringBuffer, StringBuilder)
In contentEquals () la lunghezza viene confrontata prima di qualsiasi controllo dell'istanza dell'oggetto. Se la lunghezza è la stessa, controlla che l'oggetto dell'argomento sia un'istanza di AbstractStringBuilder o meno. Se è così (cioè StringBuffer o StringBuilder), il contenuto viene controllato carattere per carattere. Nel caso in cui l'argomento sia un'istanza dell'oggetto String, allora String # equivale a String # contentEquals.
Quindi in breve,
String # equivale a confrontare il carattere carattere per carattere nel caso in cui l'argomento sia anche oggetto String. E String # contentEquals confronta il contenuto nell'oggetto caso argomento implementa l'interfaccia CharSequence.
String # contentEquals è più lento nel caso in cui confrontiamo due contenuti di stringa della stessa lunghezza di String # contentEquals chiama internamente String # uguale per oggetto String.
Nel caso in cui proviamo a confrontare oggetti con lunghezza del contenuto differente (ad esempio "abc" con "abcd"), allora String # contentEquals è più veloce di String # uguale. Perché la lunghezza viene confrontata prima di qualsiasi controllo dell'istanza dell'oggetto.
I contentEquals()
controlli metodo è il contenuto sono uguali tra String
, StringBuffer
, ecc che qualche tipo di sequenza char.
A proposito, la ragione storica della differenza è che String inizialmente non aveva una superclasse, quindi String.equals () prende una stringa come argomento. Quando CharSequence è stato introdotto come superclasse di String, aveva bisogno di un test di uguaglianza a sé stante che funzionasse su tutte le implementazioni di CharSequence e che non si scontrasse con l'equals () già utilizzato da String ... quindi abbiamo ottenuto CharSequence.contentEquals ( ), ereditato da String.
Se CharSequence fosse presente in Java 1.0, avremmo solo CharSequence.equals () e String lo implementerebbe semplicemente.
Ah, le gioie delle lingue in evoluzione ...
==
(contentEquals) e===
(uguale a) in javascript?