Was ist der Unterschied zwischen der String#equals
Methode und der String#contentEquals
Methode?
Was ist der Unterschied zwischen der String#equals
Methode und der String#contentEquals
Methode?
Antworten:
Der String#equals()
vergleicht nicht nur den Inhalt des Strings, sondern prüft auch, ob das andere Objekt ebenfalls eine Instanz von a ist String
. Der String#contentEquals()
vergleicht nur den Inhalt (die Zeichenfolge) und prüft nicht , ob das andere Objekt ebenfalls eine Instanz von ist String
. Es kann alles sein , solange es eine Implementierung ist CharSequence
der deckt ua String
, StringBuilder
, StringBuffer
, CharBuffer
etc.
==
Operator nur den Vergleich der Referenzen, nicht des Inhalts zweier Objekte.
==
erwähnte ist nur JavaScript; Es wird nie in Bezug auf Java erwähnt.
==
in JavaScript ist weit lockerer als contentEquals
, die Zahlen zum Beispiel nicht berühren,), aber Sie haben Recht über equals
eine genaue Art Spiel Überprüfung mitStrings
(anderen Klassen lockerer in ihrer mit Typen sein könnten equals
Methoden) .
Einfach ausgedrückt: String.contentEquals()
ist der klügere Bruder von String.equals()
, weil es in der Implementierung freier sein kann als String.equals()
.
Es gibt einige Gründe, warum es eine separate String.contentEquals()
Methode gibt. Der wichtigste Grund, den ich denke, ist:
equals
Methode muss reflexiv sein. Das heißt : x.equals(y) == y.equals(x)
. Dies impliziert, dass aString.equals(aStringBuffer)
dies dasselbe sein müsste wie aStringBuffer.equals(aString)
. Dies würde erfordern, dass die Java-API-Entwickler eine spezielle Implementierung für Strings in der equals()
Methode von StringBuffer, StringBuilder und CharSequence vornehmen. Das wäre ein Chaos.Dies ist , wo String.contentEquals
kommt in. Dies ist eine eigenständige Methode , die sich nicht haben , die strengen Anforderungen und Regeln für Object.equals
. Auf diese Weise können Sie den Sinn für "gleichen Inhalt" freier implementieren . Auf diese Weise können Sie beispielsweise intelligente Vergleiche zwischen einem StringBuffer und einem String durchführen.
Und um genau zu sagen, was der Unterschied ist:
String.contentEquals()
kann den Inhalt von a String
, a StringBuilder
, a StringBuffer
, a CharSequence
und allen abgeleiteten Klassen davon vergleichen. Wenn der Parameter vom Typ String ist, wird String.equals()
er ausgeführt.
String.equals()
vergleicht nur String-Objekte. Alle anderen Objekttypen gelten als ungleich.
String.contentEquals()
kann vergleichen StringBuffer
und StringBuilder
auf intelligente Weise. Es wird nicht die schwere toString()
Methode aufgerufen , die den gesamten Inhalt in ein neues String-Objekt kopiert. Stattdessen wird es mit dem zugrunde liegenden char[]
Array verglichen , was großartig ist.
Diese Antwort wurde bereits von dbw gepostet, aber er hat sie gelöscht, aber er hatte einige sehr gültige Punkte für den Unterschied beim Vergleich der Ausführungszeit, welche Ausnahmen werden ausgelöst,
Wenn Sie sich den Quellcode String # equals und String # contentEquals ansehen , ist klar, dass es zwei überschriebene Methoden für String#contentEquals
die eine StringBuilder
und die andere gibt CharSequence
.
Der Unterschied zwischen ihnen,
String#contentEquals
wird NPE auslösen, wenn das angegebene Argument lautet, null
aber String#equals
zurückgebenfalse
String#equals
vergleicht den Inhalt nur, wenn das angegebene Argument instance of String
andernfalls zurückgegeben wird. false
In allen anderen Fällen wird String#contentEquals
der Inhalt aller Objekte zurückgegeben, die die Schnittstelle implementieren CharSequence
.Sie können den Code auch so anpassen, dass String#contentEquals
das gewünschte falsche Ergebnis zurückgegeben wird, indem Sie die equals
Methode des übergebenen Arguments wie unten gezeigt überschreiben. Sie können diese Änderungen jedoch nicht vornehmen String#equals
.
Der folgende Code wird immertrue
so lange erzeugt, wie er 3 Zeichen s
enthältstring
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
wird langsamer sein als String#Equals
in dem Fall, in dem das angegebene Argument ist instance of String
und die Länge von beiden gleich String
ist, aber der Inhalt nicht gleich ist.
Beispiel , wenn die Zeichenfolge sind String s = "madam"
und String argPassed = "madan"
dann s.contentEquals(argPassed)
werden fast doppelt Ausführungszeit in diesem Fall nehmen im Vergleich zus.equals(argPassed)
Wenn die Inhaltslänge für beide Zeichenfolgen nicht gleich ist, hat die Funktion String#contentEquals
eine bessere Leistung als String#Equals
in fast allen möglichen Fällen.
Ein weiterer Punkt zu seiner Antwort
String#contentEquals
eines String
Objekts wird auch mit dem StringBuilder
Inhalt verglichen und liefert das entsprechende Ergebnis, während String#Equals
es zurückkehrtfalse
String
Klassenmethode equals(Object o)
führt nur String
Vergleiche durch. Aber contentEquals(CharSequence cs)
Prüfungen für die Klassen erstreckt sich AbstractStringBuilder
also StringBuffer
, StringBuilder
und String
Klasse auch (Sie sind alle vom Typ CharSequence
).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
Ausgabe:
false
true
Der Ausgang des ersten stmt ist , false
weil builder
nicht der Typ ist String
so equals()
kehrt false
aber die contentEquals()
Kontrollen für den Inhalt aller Art wie StringBuilder
, StringBuffer
, String
und wie der Inhalt daher gleich ist true
.
contentEquals
wird werfen, NullPointerException
wenn das angegebene Argument ist, null
aber equals()
false zurückgeben, da equals () nach instanceOf ( if (anObject instance of String)
) prüft, das false zurückgibt, wenn das Argument lautet null
.contentEquals(CharSequence cs)
::
java.lang.CharacterSequence
(zB CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
::
java.lang.String
nurRTFC :)
Da das Lesen der Quelle der beste Weg ist, sie zu verstehen, teile ich die Implementierungen beider Methoden (ab 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;
}
Es gibt eine andere Methode für String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()
und contentEquals()
sind zwei Methoden in der String
Klasse, um zwei strings
und string
mit zu vergleichenStringBuffer
.
Die Parameter von contentEquals()
sind StringBuffer
und String(charSequence)
. equals()
wird verwendet, um zwei zu vergleichen, strings
und contentEquals()
wird verwendet, um den Inhalt von String
und zu vergleichenStringBuffer
.
Methode contentEquals
und equals
sind
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Hier ist ein Code, der beide Methoden beschreibt
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);
}
}
Ausgabe:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
String # equals nimmt Object als Argument und prüft, ob es sich um eine Instanz des String-Objekts handelt oder nicht. Wenn das Argumentobjekt String Object ist, vergleicht es den Inhalt Zeichen für Zeichen. Es gibt true zurück, falls der Inhalt beider Zeichenfolgenobjekte gleich ist.
String # contentEquals die CharSequence-Schnittstelle als Argument. CharSequence kann auf zwei Arten implementiert werden: mithilfe von i) String-Klasse oder (ii) AbstractStringBuilder (übergeordnete Klasse von StringBuffer, StringBuilder)
In contentEquals () wird die Länge vor jeder Objektinstanzprüfung verglichen. Wenn die Länge gleich ist, wird überprüft, ob das Argumentobjekt eine Instanz von AbstractStringBuilder ist oder nicht. Wenn dies der Fall ist (z. B. StringBuffer oder StringBuilder), wird der Inhalt Zeichen für Zeichen überprüft. Wenn das Argument eine Instanz des String-Objekts ist, wird String # gleich von String # contentEquals aufgerufen.
Kurz gesagt,
String # equals vergleicht den Inhalt zeichenweise, falls das Argument auch String-Objekt ist. Und String # contentEquals vergleicht den Inhalt, falls das Argumentobjekt die CharSequence-Schnittstelle implementiert.
String # contentEquals ist langsamer, wenn wir zwei gleich lange String-Inhalte vergleichen, während String # contentEquals intern String # equals für String-Objekte aufruft.
Wenn wir versuchen, Objekte mit unterschiedlicher Inhaltslänge zu vergleichen (sagen wir "abc" mit "abcd"), ist String # contentEquals schneller als String # gleich. Weil die Länge vor jeder Objektinstanzprüfung verglichen wird.
Die contentEquals()
Methode überprüft , ist der Inhalt derselben zwischen a String
, StringBuffer
, usw. , die eine Art von char - Sequenz.
Übrigens ist der historische Grund für den Unterschied, dass String ursprünglich keine Oberklasse hatte, weshalb String.equals () einen String als Argument verwendet. Als CharSequence als Superklasse von String eingeführt wurde, benötigte es einen eigenen Gleichheitstest, der über alle CharSequence-Implementierungen hinweg funktionierte und nicht mit den bereits von String verwendeten equals () kollidierte ... also erhielten wir CharSequence.contentEquals ( ), die von String geerbt wird.
Wenn CharSequence in Java 1.0 vorhanden gewesen wäre, hätten wir wahrscheinlich nur CharSequence.equals () und String würde dies einfach implementieren.
Ah, die Freuden, Sprachen zu entwickeln ...
==
Ist es also wie bei den Operatoren (contentEquals) und===
(equals) in Javascript?