web-dev-qa-db-fra.com

Différence entre les méthodes String # equals et String # contentEquals

Quelle est la différence entre le String#equals la méthode et la String#contentEquals méthode?

126
Arathana

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.

142
BalusC

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:

  • La méthode 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.

35
Martijn Courteaux

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,

  1. String#contentEquals Lancera NPE si l'argument fourni est null mais String#equals Renverra false
  2. 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 .
  3. 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;
            }
        }));
    
  4. 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)

  5. 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

  1. 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
29
Prateek

contentEquals(CharSequence cs):

  • Vous permet de vérifier l'égalité de la valeur de chaîne donnée avec n'importe quelle instance d'implémentation de l'interface Java.lang.CharacterSequence (Par exemple, CharBuffer, Segment, String, StringBuffer , StringBuilder)

equals(Object anObject):

  • Vous permet de vérifier l’égalité de la valeur de chaîne donnée avec n’importe quelle instance de type Java.lang.Stringniquement

RTFC:)

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);
    }
}
13
Amit Sharma
  • 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.
10
Trying

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
8
Asfab

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.

6
fastcodejava

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.

6
Anirban Pal

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 ...

5
keshlam