Comment comparer les chaînes en Java?


J'ai utilisé l'opérateur == dans mon programme pour comparer toutes mes chaînes jusqu'à présent. Cependant, j'ai rencontré un bogue, changé l'un d'eux en .equals() à la place, et il a corrigé le bogue.

Est == mauvais? Quand devrait-il et ne devrait-il pas être utilisé? Quelle est la différence?

Author: Nathan H , 2009-02-05

23 answers

== teste l'égalité de référence (s'ils sont le même objet).

.equals() teste l'égalité de valeur (si elles sont logiquement "égales").

Objets.equals () vérifie null avant d'appeler .equals() donc vous n'avez pas à le faire (disponible à partir de JDK7, également disponible dans Guava ).

Chaîne de caractères.contentEquals () compare le contenu du String avec le contenu de tout CharSequence (disponible depuis Java 1.5).

Par conséquent, si vous vous voulez tester si deux chaînes ont la même valeur, vous voudrez probablement utiliser Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

, Vous avez presque toujours voulez utiliserObjects.equals(). Dans la situation rareoù vous savezque vous avez affaire à des chaînes internées, vous pouvez utiliser ==.

De JLS 3.10.5. Littéraux De Chaîne:

De plus, un littéral de chaîne fait toujours référence à l'instance same de la classe String. C'est parce que littéraux de chaîne-ou, plus généralement, chaînes qui sont les valeurs d'expressions constantes(§15.28) - sont "internés" de manière à partager des instances uniques, en utilisant la méthode String.intern.

Exemples Similaires peuvent également être trouvés dans JLS 3.10.5-1.

 5070
Author: Aaron Maenpaa, 2018-07-12 13:27:59

== teste les références d'objet, .equals() teste les valeurs de chaîne.

Parfois, il semble que == compare des valeurs, car Java fait des choses en coulisse pour s'assurer que les chaînes en ligne identiques sont en fait le même objet.

Par exemple:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Mais méfiez-vous des nuls!

== gère bien les chaînes null, mais appeler .equals() à partir d'une chaîne nulle provoquera une exception:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Donc, si vous savez que fooString1 peut être null, dites au lecteur qu'en écrivant

System.out.print(fooString1 != null && fooString1.equals("bar"));

Ce qui suit est plus court, mais il est moins évident qu'il vérifie null (à partir de Java 7):

System.out.print(Objects.equals(fooString1, "bar"));
 636
Author: Whatsit, 2018-05-24 15:48:08

== compare les références d'objets.

.equals() compare les valeurs de Chaîne.

Parfois, {[5] } donne des illusions de comparaison des valeurs de chaîne, comme dans les cas suivants:

String a="Test";
String b="Test";
if(a==b) ===> true

En effet, lorsque vous créez un littéral de chaîne, la JVM recherche d'abord ce littéral dans le pool de chaînes, et si elle trouve une correspondance, cette même référence sera donnée à la nouvelle chaîne. Pour cette raison, nous obtenons:

(a= = b) = = = > vrai

                       String Pool
     b -----------------> "test" <-----------------a

Cependant, == échoue dans le cas suivant:

String a="test";
String b=new String("test");
if (a==b) ===> false

Dans ce cas, pour new String("test"), l'instruction new String sera créée sur le tas, et cette référence sera donnée à b, donc b recevra une référence sur le tas, pas dans le pool de chaînes.

Maintenant a pointe vers une chaîne dans le pool de chaînes tandis que b pointe vers une chaîne sur le tas. À cause de cela, nous obtenons:

Si (a= = b) = = = > faux.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Tout .equals() compare toujours une valeur de Chaîne de sorte qu'il donne vrai dans les deux cas:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Donc utiliser .equals() est toujours mieux.

 404
Author: Ganesh, 2018-02-08 19:15:59

Le == opérateur vérifie si les deux chaînes sont exactement le même objet.

La méthode .equals() vérifiera si les deux chaînes ont la même valeur.

 205
Author: Clayton, 2013-12-24 07:49:45

Les chaînes en Java sont immuables. Cela signifie que chaque fois que vous essayez de changer/modifier la chaîne, vous obtenez une nouvelle instance. Vous ne pouvez pas modifier la chaîne d'origine. Cela a été fait pour que ces instances de chaîne puissent être mises en cache. Un programme typique contient beaucoup de références de chaîne et la mise en cache de ces instances peut diminuer l'empreinte mémoire et augmenter les performances du programme.

Lorsque vous utilisez = = operator pour la comparaison de chaînes, vous ne comparez pas le contenu de la chaîne, mais en fait en comparant l'adresse mémoire. S'ils sont tous deux égaux, cela retournera vrai et faux sinon. Alors que equals in string compare le contenu de la chaîne.

La question est donc de savoir si toutes les chaînes sont mises en cache dans le système, comment se fait-il que == renvoie false alors que equals renvoie true? Eh bien, c'est possible. Si vous créez une nouvelle chaîne comme String str = new String("Testing"), vous finissez par créer une nouvelle chaîne dans le cache même si le cache contient déjà une chaîne ayant le même contenu. En bref "MyString" == new String("MyString") retournera toujours faux.

Java parle également de la fonction intern() qui peut être utilisée sur une chaîne pour la faire partie du cache afin que "MyString" == new String("MyString").intern() renvoie true.

Remarque: == operator est beaucoup plus rapide que equals simplement parce que vous comparez deux adresses mémoire, mais vous devez être sûr que le code ne crée pas de nouvelles instances de chaîne dans le code. Sinon vous rencontrerez des bugs.

 156
Author: Faisal Feroz, 2018-02-08 19:10:28
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

Assurez-vous de comprendre pourquoi. C'est parce que la comparaison == ne compare que les références; la méthode equals() fait une comparaison caractère par caractère du contenu.

Lorsque vous appelez nouveau pour a et b, chacun reçoit une nouvelle référence qui pointe vers la "foo" dans la table des chaînes. Les références sont différentes, mais le contenu est le même.

 134
Author: duffymo, 2013-11-09 12:50:59

Oui, c'est mauvais...

== signifie que vos deux références de chaîne sont exactement le même objet. Vous avez peut-être entendu dire que c'est le cas car Java conserve une sorte de table littérale (ce qu'il fait), mais ce n'est pas toujours le cas. Certaines chaînes sont chargées de différentes manières, construites à partir d'autres chaînes, etc., vous ne devez donc jamais supposer que deux chaînes identiques sont stockées au même emplacement.

Equals fait la vraie comparaison pour vous.

 115
Author: Uri, 2017-11-19 08:16:08

Oui, == est mauvais pour comparer des chaînes (tous les objets vraiment, sauf si vous savez qu'ils sont canoniques). == compare simplement les références d'objets. .equals() tests d'égalité. Pour les chaînes, elles seront souvent les mêmes, mais comme vous l'avez découvert, ce n'est pas toujours garanti.

 110
Author: cletus, 2014-12-17 08:28:55

Java a un pool de chaînes sous lequel Java gère l'allocation de mémoire pour les objets String. Voir Chaîne de Piscines en Java

Lorsque vous vérifiez (comparez) deux objets à l'aide de l'opérateur ==, il compare l'égalité d'adresse dans le pool de chaînes. Si les deux objets String ont les mêmes références d'adresse, il renvoie true, sinon false. Mais si vous voulez comparer le contenu de deux objets String, vous devez remplacer la méthode equals.

equals est en fait la méthode de la classe Object, mais elle est remplacée par la classe String et une nouvelle définition est donnée qui compare le contenu de l'objet.

Example:
    stringObjectOne.equals(stringObjectTwo);

Mais attention, il respecte le cas de String. Si vous voulez une comparaison insensible à la casse, vous devez opter pour la méthode equalsIgnoreCase de la classe String.

Voyons:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE
 105
Author: Saurabh Agarwal, 2018-02-08 19:19:10

.equals() compare les données d'une classe (en supposant que la fonction est implémentée). == compare les emplacements du pointeur (emplacement de l'objet en mémoire).

== renvoie true si les deux objets (NE PARLANT PAS DE PRIMITIVES) pointent vers la MÊME instance d'objet. .equals() retourne vrai si les deux objets contiennent les mêmes données equals() Rapport == en Java

Cela peut vous aider.

 92
Author: Matt Razza, 2014-12-17 08:30:43

== compare les références d'objets en Java , et cela ne fait pas exception pour les objets String.

Pour comparer le contenu réel des objets (y compris String), il faut utiliser la méthode equals .

Si une comparaison de deux objets String utilisant == s'avère être true, c'est parce que les objets String ont été internés et que la machine virtuelle Java a plusieurs références pointent vers la même instance de String. Il ne faut pas s'attendre à ce que la comparaison d'un String objet contenant le même contenu qu'un autre String objet utilisant == pour évaluer comme true.

 91
Author: coobird, 2009-02-04 23:20:08

Je suis d'accord avec la réponse de zacherates.

Mais ce que vous pouvez faire est d'appeler intern() sur vos chaînes non littérales.

De l'exemple de zacherates:

// ... but they are not the same object
new String("test") == "test" ==> false 

Si vous internez l'égalité de chaîne non littérale est true

new String("test").intern() == "test" ==> true 
 88
Author: pgras, 2018-09-21 01:53:32

== effectue une référence vérification de l'égalité, si les 2 objets (chaînes dans ce cas) se réfèrent au même objet dans la mémoire.

Le equals() méthode vérifie si la contenu ou unis de 2 objets sont les mêmes.

Évidemment == est plus rapide, mais donnera (pourrait) donner de faux résultats dans de nombreux cas si vous voulez juste dire si 2 Strings contiennent le même texte.

Certainement l'utilisation de equals() méthode est recommandé.

Ne vous inquiétez pas de la performance. Quelques choses à encourager à utiliser String.equals():

  1. L'implémentation de String.equals() vérifie d'abord l'égalité de référence (en utilisant ==), et si les 2 chaînes sont les mêmes par référence, aucun autre calcul n'est effectué!
  2. Si les 2 références de chaîne ne sont pas les mêmes, String.equals() vérifiera ensuite les longueurs des chaînes. C'est aussi une opération rapide car la classe String stocke la longueur de la chaîne, pas besoin de compter le caractères ou points de code. Si les longueurs diffèrent, aucune autre vérification n'est effectuée, nous savons qu'elles ne peuvent pas être égales.
  3. Ce n'est que si nous sommes arrivés jusque-là que le contenu des 2 chaînes sera réellement comparé, et ce sera une comparaison à main courte: tous les caractères ne seront pas comparés, si nous trouvons un caractère inadéquat (à la même position dans les 2 chaînes), aucun autre caractère ne sera vérifié.

Quand tout est dit et fait, même si nous avons la garantie que les chaînes sont les stagiaires, en utilisant la méthode equals() n'est toujours pas cette surcharge que l'on pourrait penser, certainement la manière recommandée. Si vous voulez une vérification efficace des références, utilisez enums où il est garanti par la spécification du langage et l'implémentation que la même valeur enum sera le même objet (par référence).

 87
Author: icza, 2015-08-11 06:40:30

Si vous êtes comme moi, quand j'ai commencé à utiliser Java, je voulais utiliser l'opérateur "==" pour tester si deux instances de chaîne étaient égales, mais pour le meilleur ou pour le pire, ce n'est pas la bonne façon de le faire en Java.

Dans ce tutoriel, je vais démontrer plusieurs façons différentes de comparer correctement les chaînes Java, en commençant par l'approche que j'utilise la plupart du temps. À la fin de ce tutoriel de comparaison de chaînes Java, je vais également expliquer pourquoi l'opérateur "= = " ne fonctionne pas lors de la comparaison de Java chaîne.

Option 1: Comparaison de chaînes Java avec la méthode equals La plupart du temps (peut-être 95% du temps), je compare les chaînes avec la méthode equals de la classe Java String, comme ceci:

if (string1.equals(string2))

Cette méthode String equals examine les deux chaînes Java, et si elles contiennent exactement la même chaîne de caractères, elles sont considérées comme égales.

En regardant un exemple de comparaison rapide de chaînes avec la méthode equals, si le test suivant a été exécuté, les deux les chaînes ne seraient pas considérées comme égales car les caractères ne sont pas exactement les mêmes (le cas des caractères est différent):

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

, Mais, lorsque les deux chaînes contiennent exactement la même chaîne de caractères, la méthode equals renvoie true, comme dans cet exemple:

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Option 2: Comparaison de chaînes avec la méthode equalsIgnoreCase

Dans certains tests de comparaison de chaînes, vous voudrez ignorer si les chaînes sont majuscules ou minuscules. Quand vous voulez testez vos chaînes pour l'égalité de cette manière insensible à la casse, utilisez la méthode equalsIgnoreCase de la classe String, comme ceci:

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

Option 3: Comparaison de chaînes Java avec la méthode compareTo

Il existe également une troisième façon moins courante de comparer les chaînes Java, et c'est avec la méthode String class compareTo. Si les deux chaînes sont exactement les mêmes, la méthode compareTo renverra une valeur de 0 (zéro). Voici un exemple rapide de ce que cette comparaison de chaînes l'approche ressemble à:

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Pendant que j'écris sur ce concept d'égalité en Java, il est important de noter que le langage Java inclut une méthode equals dans la classe d'objet Java de base. Chaque fois que vous créez vos propres objets et que vous souhaitez fournir un moyen de voir si deux instances de votre objet sont "égales", vous devez remplacer (et implémenter) cette méthode equals dans votre classe (de la même manière que le langage Java fournit ce comportement d'égalité/comparaison dans la chaîne equals méthode).

Vous voudrez peut-être jeter un oeil à ce ==, .equals(), compareTo(), et de comparer()

 78
Author: Mohamed E. ManSour, 2016-03-16 15:00:47

Fonction:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

Test:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);
 73
Author: Khaled.K, 2016-09-09 11:55:23

L'opérateur == vérifie si les deux références pointent vers le même objet ou non. .equals() vérifiez le contenu réel de la chaîne (valeur).

Notez que la méthode .equals() appartient à la classe Object (super classe de toutes les classes). Vous devez le remplacer selon vos exigences de classe, mais pour String, il est déjà implémenté et vérifie si deux chaînes ont la même valeur ou non.

  • Cas 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true
    

    Raison: Les littéraux de chaîne créés sans null sont stocké dans le pool de chaînes dans la zone permgen du tas. Donc, s1 et s2 pointent vers le même objet dans le pool.

  • Cas 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true
    

    Raison: Si vous créez un objet String en utilisant le mot clé new un espace séparé lui est alloué sur le tas.

 67
Author: Aniket Thakur, 2018-02-08 19:30:03

== compare la valeur de référence des objets alors que la méthode equals() présente dans la classe java.lang.String compare le contenu de l'objet String (à un autre objet).

 49
Author: samkit shah, 2014-03-04 20:19:10

Je pense que lorsque vous définissez un String de la définition d'un objet. Vous devez donc utiliser .equals(). Lorsque vous utilisez des types de données primitifs, vous utilisez == mais avec String (et tout objet), vous devez utiliser .equals().

 47
Author: fabricioflores, 2014-12-17 08:31:39

Si la méthode equals() est présente dans la classe java.lang.Object, et qu'elle devrait vérifier l'équivalence de l'état des objets! Cela signifie que le contenu des objets. Alors que l'opérateur == est censé vérifier que les instances d'objet réelles sont identiques ou non.

Exemple

Considérons deux variables de référence, str1 et str2:

str1 = new String("abc");
str2 = new String("abc");

Si vous utilisez equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

, Vous obtiendrez la sortie TRUE si vous utilisez ==.

System.out.println((str1==str2) ? "TRUE" : "FALSE");

Maintenant, vous obtiendrez le FALSE en sortie, car str1 et str2 pointent vers deux objets différents même si les deux partagent le même contenu de chaîne. C'est à cause de new String() qu'un nouvel objet est créé à chaque fois.

 42
Author: Rakesh KR, 2018-02-08 19:33:11

Opérateur == est toujours destiné à comparaison de référence d'objet , alors que la classe de chaîne .equals() la méthode est remplacée pour comparaison de contenu :

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)
 39
Author: sham.y, 2018-02-08 19:20:12

Tous les objets sont garantis d'avoir une méthode .equals() puisque Object contient une méthode, .equals(), qui renvoie un booléen. Il appartient à la sous-classe de remplacer cette méthode si une définition supplémentaire est requise. Sans cela (c'est-à-dire en utilisant ==), seules les adresses mémoire sont vérifiées entre deux objets pour l'égalité. String remplace cette méthode .equals() et au lieu d'utiliser l'adresse mémoire, elle renvoie la comparaison des chaînes au niveau des caractères pour l'égalité.

Une note clé est que les chaînes sont stockées dans un pool forfaitaire, donc une fois qu'une chaîne est créée, elle est stockée pour toujours dans un programme à la même adresse. Les chaînes ne changent pas, elles sont immuables. C'est pourquoi c'est une mauvaise idée d'utiliser la concaténation de chaînes régulière si vous avez beaucoup de traitement de chaînes à faire. Au lieu de cela, vous utiliseriez les classes StringBuilder fournies. Rappelez-vous que les pointeurs vers cette chaîne peuvent changer et si vous étiez intéressé de voir si deux pointeurs étaient les mêmes == serait une bonne façon de procéder. Chaîne eux-mêmes ne le font pas.

 36
Author: James, 2018-02-08 19:12:44

Vous pouvez également utiliser la méthode compareTo() pour comparer deux chaînes. Si le compareTo résultat est 0, alors les deux chaînes sont égales, sinon les chaînes comparées ne sont pas égaux.

Le == compare les références et ne compare pas les chaînes réelles. Si vous avez créé chaque chaîne en utilisant new String(somestring).intern(), vous pouvez utiliser l'opérateur == pour comparer deux chaînes, sinon les méthodes equals() ou compareTo ne peuvent être utilisées que.

 36
Author: AlvaroAV, 2018-02-08 19:21:07

En Java, lorsque le "==" l'opérateur est utilisé pour comparer 2 objets, il vérifie si les objets font référence à la même place en mémoire. En d'autres termes, il vérifie si les 2 noms d'objets sont essentiellement des références au même emplacement de mémoire.

La classe Java String remplace en fait l'implémentation par défaut equals() dans la classe Object – et elle remplace la méthode afin qu'elle vérifie uniquement les valeurs des chaînes, pas leurs emplacements en mémoire. Cela signifie que si vous appelez la méthode equals () pour comparer 2 objets String, puis tant que la séquence réelle de caractères est égale, les deux objets sont considérés comme égaux.

Le == opérateur vérifie si les deux chaînes sont exactement le même objet.

La méthode .equals() vérifie si les deux chaînes ont la même valeur.

 34
Author: Lijo, 2014-08-04 00:48:38