Quelle est la différence entre la String#equals
méthode et la String#contentEquals
méthode?
Quelle est la différence entre la String#equals
méthode et la String#contentEquals
méthode?
Réponses:
Le String#equals()
non seulement compare le contenu de la chaîne, mais aussi vérifie si l'autre objet est une instance d'un String
. Le String#contentEquals()
seul compare le contenu (la séquence de caractères) et ne vérifie pas si l'autre objet est également une instance de String
. Il peut être tout aussi longtemps qu'il est une mise en œuvre CharSequence
qui couvre ao String
, StringBuilder
, StringBuffer
, CharBuffer
, etc.
==
opérateur vous permettra uniquement de comparer les références et non le contenu de deux objets.
==
mentionné n'est que JavaScript; il n'est jamais mentionné concernant Java.
==
en JavaScript, c'est beaucoup plus lâche que contentEquals
, ce qui ne touchera pas aux nombres, par exemple), mais vous avez raison de equals
vérifier une correspondance de type exacte avecStrings
(d'autres classes peuvent être plus lâches avec des types dans leurs equals
méthodes) .
Pour le dire facilement: String.contentEquals()
est le frère le plus intelligent de String.equals()
, car il peut être plus libre dans la mise en œuvre que String.equals()
.
Il existe certaines raisons pour lesquelles il existe une String.contentEquals()
méthode distincte . La raison la plus importante à mon avis est:
equals
méthode doit être réflexive. Cela signifie que: x.equals(y) == y.equals(x)
. Cela implique que cela aString.equals(aStringBuffer)
devrait être le même que aStringBuffer.equals(aString)
. Cela nécessiterait que les développeurs d'API Java réalisent également une implémentation spéciale pour Strings dans la equals()
méthode StringBuffer, StringBuilder et CharSequence. Ce serait un gâchis.C'est là String.contentEquals
qu'intervient. Il s'agit d'une méthode autonome qui n'a pas à suivre les exigences et les règles strictes pour Object.equals
. De cette façon, vous pouvez mettre en œuvre le sens de «contenu égal» plus librement. Cela vous permet de faire des comparaisons intelligentes entre un StringBuffer et un String, par exemple.
Et pour dire quelle est exactement la différence:
String.contentEquals()
peut comparer le contenu de a String
, a StringBuilder
, a StringBuffer
, a CharSequence
et toutes les classes dérivées de ceux-ci. Si le paramètre est de type String, alors String.equals()
soyez exécuté.
String.equals()
compare uniquement les objets String. Tous les autres types d'objets sont considérés comme différents.
String.contentEquals()
peut comparer StringBuffer
et StringBuilder
de manière intelligente. Il n'appelle pas la toString()
méthode lourde , qui copie tout le contenu dans un nouvel objet String. Au lieu de cela, il se compare au char[]
tableau sous-jacent , ce qui est excellent.
Cette réponse était déjà postée par dbw mais il l'a supprimée mais il avait des points très valables pour la différence en comparant le temps d'exécution, les exceptions levées,
Si vous regardez le code source String # equals et String # contentEquals, il est clair qu'il existe deux méthodes remplacées pour l' String#contentEquals
une qui prennent StringBuilder
et l'autre CharSequence
.
La différence entre eux,
String#contentEquals
lancera NPE si l'argument fourni est null
mais String#equals
retournerafalse
String#equals
compare le contenu uniquement lorsque l'argument fourni est instance of String
sinon il retournera false
dans tous les autres cas mais par contre String#contentEquals
vérifie le contenu de tous les objets qui implémentent l'interface CharSequence
.Vous pouvez également modifier le code pour String#contentEquals
renvoyer le mauvais résultat ou le résultat souhaité en remplaçant la equals
méthode de l'argument transmis comme indiqué ci-dessous, mais vous ne pouvez pas effectuer ces modifications avec String#equals
.
Le code ci-dessous produira toujourstrue
tant qu'il s
contient tout string
ce qui est long de 3 caractères
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
sera plus lent que String#Equals
dans le cas où l'argument fourni est instance of String
et la longueur des deux String
est la même mais le contenu n'est pas égal.
Exemple si la chaîne est String s = "madam"
et prendra String argPassed = "madan"
alors s.contentEquals(argPassed)
presque le double du temps d'exécution dans ce cas par rapport às.equals(argPassed)
Si la longueur du contenu n'est pas la même pour les deux chaînes, la fonction String#contentEquals
aura de meilleures performances que String#Equals
dans presque tous les cas possibles.
Encore un point à ajouter à sa réponse
String#contentEquals
d'un String
objet sera également comparé au StringBuilder
contenu et fournira le résultat approprié tandis que String#Equals
retournerafalse
String
La equals(Object o)
méthode de classe ne fait que la String
comparaison. Mais contentEquals(CharSequence cs)
vérifie les classes étend, AbstractStringBuilder
c'est -à- dire StringBuffer
, StringBuilder
et String
classe aussi (ils sont tous de type CharSequence
).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
production:
false
true
La sortie de la première stmt est false
parce builder
est pas de type String
si les equals()
rendements , false
mais les contentEquals()
contrôles pour le contenu de tout type comme StringBuilder
, StringBuffer
, String
et que le contenu est donc même true
.
contentEquals
lancera NullPointerException
si l'argument fourni est null
mais equals()
retournera false car equals () vérifie instanceOf ( if (anObject instance of String)
) qui retourne false si l'argument est null
.contentEquals(CharSequence cs)
:
java.lang.CharacterSequence
(par exemple CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
:
java.lang.String
uniquementRTFC :)
Puisque la lecture de la source est la meilleure façon de la comprendre, je partage les implémentations des deux méthodes (à partir de 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;
}
Il existe une autre méthode de String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()
et il contentEquals()
existe deux méthodes en String
classe pour comparer deux strings
et string
avec StringBuffer
.
Les paramètres de contentEquals()
sont StringBuffer
et String(charSequence)
. equals()
est utilisé pour comparer deux strings
et contentEquals()
est utilisé pour comparer le contenu de String
et StringBuffer
.
Méthode contentEquals
et equals
sont
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Voici un code qui décrit les deux méthodes
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);
}
}
Production:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
String # equals prend Object comme argument et vérifie qu'il s'agit d'une instance de l'objet String ou non. Si l'objet argument est String Object, il compare le contenu caractère par caractère. Elle renvoie true si le contenu des deux objets chaîne est le même.
String # contentEquals prend l'interface CharSequence comme argument. CharSequence peut être implémenté de 2 façons - en utilisant i) la classe String ou (ii) AbstractStringBuilder (classe parent de StringBuffer, StringBuilder)
Dans contentEquals (), la longueur est comparée avant toute vérification d'instance d'objet. Si la longueur est la même, alors il vérifie que l'argument est une instance de AbstractStringBuilder ou non. Si tel est le cas (c'est-à-dire StringBuffer ou StringBuilder), le contenu est vérifié caractère par caractère. Si l'argument est une instance de l'objet String, String # est égal à appelé à partir de String # contentEquals.
Donc en bref,
String # equals compare le contenu caractère par caractère si l'argument case est également un objet String. Et String # contentEquals compare le contenu dans le cas où l'objet argument implémente l'interface CharSequence.
String # contentEquals est plus lent si nous comparons deux contenus de chaîne de même longueur que String # contentEquals appelle en interne String # equals pour l'objet String.
Dans le cas où nous essayons de comparer des objets avec une longueur de contenu différente (disons "abc" avec "abcd"), alors String # contentEquals est plus rapide que String # equals. Parce que la longueur est comparée avant toute vérification d'instance d'objet.
Les contentEquals()
contrôles de procédé est le contenu sont identiques entre String
, StringBuffer
etc qui une sorte de séquence de carbonisation.
BTW, la raison historique de la différence est que String n'avait pas à l'origine de superclasse, donc String.equals () prend une String comme argument. Lorsque CharSequence a été introduit comme la superclasse de String, il lui fallait un test d'égalité qui fonctionnait sur toutes les implémentations de CharSequence, et qui n'entrerait pas en conflit avec equals () déjà utilisé par String ... donc nous avons obtenu CharSequence.contentEquals ( ), hérité de String.
Si CharSequence était présent dans Java 1.0, nous n'aurions probablement que CharSequence.equals () et String implémenterait simplement cela.
Ah, les joies de l'évolution des langues ...
==
(contentEquals) et===
(equals) en javascript?