Quelle est la différence entre le String#equals
la méthode et la String#contentEquals
méthode?
Le String#equals()
non seulement compare le contenu de String, mais vérifie également si l'autre objet est également une instance d'un String
. Le String#contentEquals()
ne compare que le contenu (la séquence de caractères) et ne pas vérifie si l'autre objet est aussi une instance de String
. Cela peut être n'importe quoi tant que c'est une implémentation de CharSequence
qui couvre a.o. String
, StringBuilder
, StringBuffer
, CharBuffer
, etc.
Pour le dire facilement: String.contentEquals()
est le frère 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 méthode String.contentEquals()
séparée. La raison la plus importante que je pense est:
equals
doit être réflexive. Cela signifie que: x.equals(y) == y.equals(x)
. Cela implique que aString.equals(aStringBuffer)
devrait être identique à aStringBuffer.equals(aString)
. Cela nécessiterait que les développeurs de l'API Java) apportent une implémentation spéciale aux chaînes dans la méthode equals()
de StringBuffer, StringBuilder et CharSequence. Ce serait un désordre.Donc, et c’est là que String.contentEquals
Entre en jeu. C’est une méthode autonome qui fait pas doit suivre les exigences et règles strictes pour Object.equals
. De cette façon, vous pouvez implémenter le sens de "contenu égal" plus librement. Cela vous permet par exemple de faire des comparaisons intelligentes entre StringBuffer et String.
Et pour dire quelle est exactement la différence:
String.contentEquals()
peut comparer le contenu d'un String
, d'un StringBuilder
, d'un StringBuffer
, d'un CharSequence
et de toutes leurs classes dérivées. Si le paramètre est de type String, alors String.equals()
sera exécuté.
String.equals()
compare uniquement les objets String. Tous les autres types d'objets sont considérés comme non égaux.
String.contentEquals()
peut comparer StringBuffer
et StringBuilder
de manière intelligente. Elle appelle not appelle la méthode lourde toString()
, qui copie tout le contenu dans un nouvel objet String. Au lieu de cela, il compare avec le tableau sous-jacent char[]
, Ce qui est excellent.
Cette réponse a déjà été 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, quelles exceptions sont levées,
Si vous regardez le code source String # est égal à et String # contentEquals , il est clair qu'il existe deux méthodes remplacées pour String#contentEquals
Qui utilisent StringBuilder
et autres CharSequence
.
La différence entre eux,
String#contentEquals
Lancera NPE si l'argument fourni est null
mais String#equals
Renverra false
String#equals
Compare le contenu uniquement lorsque l'argument fourni est instance of String
, Sinon il retournera false
dans tous les autres cas sauf que String#contentEquals
Vérifie le contenu de tous les objets qui implémentent l'interface CharSequence
.Vous pouvez également modifier le code pour que String#contentEquals
Renvoie le ou les résultats souhaités en redéfinissant la méthode equals
de l'argument transmis comme indiqué ci-dessous, mais vous ne pouvez pas effectuer ces modifications avec String#equals
.
Le code ci-dessous produira toujours true
tant que s
contient n'importe quel élément string
qui a 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 que la longueur des deux String
est identique mais que le contenu n'est pas égal.
Exemple si la chaîne est String s = "madam"
Et String argPassed = "madan"
, Alors s.contentEquals(argPassed)
sera prend presque le double de 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.
Un dernier point à ajouter à sa réponse
String#contentEquals
D'un objet String
sera également comparé au contenu de StringBuilder
et fournira le résultat approprié tandis que String#Equals
Renverra false
contentEquals(CharSequence cs)
:
Java.lang.CharacterSequence
(Par exemple, CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
:
Java.lang.String
niquementRTFC:)
Puisque la lecture du code source est la meilleure façon de le 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);
}
}
String
class equals(Object o)
la méthode n'effectue que String
comparaison. Mais contentEquals(CharSequence cs)
vérifie les classes et étend AbstractStringBuilder
c'est-à-dire StringBuffer
, StringBuilder
et String
class également (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));
sortie:
false
true
La sortie du premier fichier stmt est false
car builder
n’est pas de type String
so equals()
renvoie false
mais la fonction contentEquals()
vérifie le contenu de tous les types tels que StringBuilder
, StringBuffer
, String
et que le contenu est identique, donc 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 renvoie false si l'argument est null
.equals()
et contentEquals()
sont deux méthodes de la classe String
permettant de 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
.
Les méthodes 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);
}
}
Sortie:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
La méthode contentEquals()
vérifie si le contenu est identique entre un String
, StringBuffer
, etc., avec une sorte de séquence de caractères.
String # equals prend Object en argument et vérifie s'il s'agit ou non d'une instance de l'objet String. Si l'objet argument est String Object, il compare le contenu caractère par caractère. Il renvoie true si le contenu des deux objets chaîne est identique.
String # contentEquals prend l'interface CharSequence en tant qu'argument. CharSequence peut être implémenté de deux manières différentes: i) classe String ou (ii) AbstractStringBuilder (classe parente de StringBuffer, StringBuilder).
Dans contentEquals (), la longueur est comparée avant toute vérification d'instance d'objet. Si length est identique, il vérifie que l'objet 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. Dans le cas où argument est une instance de l'objet String, String # est égal à appelé à partir de String # contentEquals.
En bref,
String # equals compare le contenu caractère par caractère dans le cas où l'argument est également un objet Chaîne. Et String # contentEquals compare le contenu dans le cas où l'argument argument implémente l'interface CharSequence.
String # contentEquals est plus lent si nous comparons le même contenu de chaîne que String # contentEquals appelle en interne String # est égal à l'objet String.
Si nous essayons de comparer des objets dont la longueur du contenu est différente (par exemple, "abc" avec "abcd"), String # contentEquals est plus rapide que String # égal à. Parce que la longueur est comparée avant toute vérification d'instance d'objet.
BTW, la raison historique de la différence est que String n’avait pas de superclasse à l’origine, donc String.equals () prend un String comme argument. Lorsque CharSequence a été présenté comme la super-classe de String, il lui fallait un test d’égalité lui-même, qui s’appliquait dans toutes les implémentations de CharSequence. ), qui est hérité par String.
Si CharSequence a été présent dans Java 1.0, nous n’aurions probablement que CharSequence.equals () et String l’implémenterait simplement.
Ah, les joies des langues en évolution ...