Comment comparer des chaînes en Java?

724

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

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

Nathan H
la source
12
Il est également bon de savoir que, si vous remplacez la méthode .equals (), assurez-vous de remplacer la méthode .hashcode (), sinon vous finirez par violer la relation d'équivalence b / w equals et hashcode. Pour plus d'informations, reportez-vous au doc ​​java.
Nageswaran
Laisser un lien vers mon explication sur les raisons pour lesquelles ==cela fonctionne sur les objets: stackoverflow.com/a/19966154/2284641
Johannes H.
==fonctionnera une partie du temps, car java a un pool de chaînes, où il essaie de réutiliser les références de mémoire des chaînes couramment utilisées. Mais ==compare que les objets sont égaux, pas les valeurs ... tout .equals()comme l'utilisation appropriée que vous souhaitez utiliser.
James Oravec
N'utilisez jamais == pour tester si les chaînes sont identiques, sauf si vous aimez rechercher des erreurs subtiles et étudier les subtilités du processus d'internement de chaînes Java. "12"=="1"+2est faux (probablement)
Flight Odyssey

Réponses:

5564

== teste l'égalité de référence (s'il s'agit du même objet).

.equals() teste l'égalité des valeurs (qu'elles soient logiquement "égales").

Objects.equals () vérifie nullavant d'appeler .equals()afin que vous n'ayez pas à le faire (disponible à partir de JDK7, également disponible dans Guava ).

Par conséquent, si vous souhaitez tester si deux chaînes ont la même valeur, vous voudrez probablement l'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 voulez presque toujours l' utiliser Objects.equals(). Dans la rare situation où vous savez que vous avez affaire à des chaînes internes , vous pouvez utiliser ==.

À partir de JLS 3.10.5. Littéraux de chaîne :

De plus, un littéral de chaîne fait toujours référence à la même instance de classe String. En effet, les littéraux de chaîne - ou, plus généralement, les chaînes qui sont les valeurs d'expressions constantes ( §15.28 ) - sont "internés" afin de partager des instances uniques, en utilisant la méthode String.intern.

Des exemples similaires peuvent également être trouvés dans JLS 3.10.5-1 .

Autres méthodes à considérer

String.equalsIgnoreCase () égalité de valeur qui ignore la casse.

String.contentEquals () compare le contenu de l ' Stringavec le contenu de any CharSequence(disponible depuis Java 1.5). Vous évite d'avoir à transformer votre StringBuffer, etc. en une chaîne avant de faire la comparaison d'égalité, mais vous laisse la vérification nulle.

Aaron Maenpaa
la source
3
Si == vérifie l'égalité de référence, pourquoi n == 5 est-il logique? 5 n'est pas une variable
Hrit Roy
2
@HritRoy Car ==vérifie la valeur d'une variable. Lorsque vous avez un objet, la variable qui référence l'objet a la référence de l'objet comme valeur . Ainsi, vous comparez les références lorsque vous comparez deux variables avec ==. Lorsque vous comparez un type de données primitif tel que int, c'est toujours le même cas. Une variable de type inta l'entier comme valeur. Ainsi, vous comparez les valeurs de deux ints en utilisant ==. Si intest la valeur d'une variable ou d'un nombre magique, peu importe. De plus: Une référence n'est rien d'autre qu'un nombre qui fait référence à la mémoire.
akuzminykh
718

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

Parfois, il semble que les ==valeurs soient comparées, car Java effectue des opérations en arrière-plan pour s'assurer que des chaînes en ligne identiques sont bien 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 attention aux nulls!

==gère nullcorrectement les chaînes, 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 cela fooString1peut être nul, dites au lecteur qu'en écrivant

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

Les éléments suivants sont plus courts, mais il est moins évident qu'il vérifie la valeur null:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required
Whatsit
la source
86
Parfois , il semble que « == » compare les valeurs, - == faire des valeurs toujours comparer! (C'est juste que certaines valeurs sont des références!)
aioobe
6
Hélas, il n'y a pas de méthode statique pour isNullOrEmpty (), et pas de surcharge personnalisée des opérateurs, ce qui rend cette partie de Java plus encombrante qu'en C # ou Python. Et comme Java n'a pas de méthodes d'extension, vous ne pouvez pas écrire votre propre utilitaire pour étendre java.lang.String. Droite? Des réflexions sur le sous-classement de String, l'ajout de cette méthode d'utilité statique, puis l'utilisation de MyString à la place? Une méthode statique avec deux paramètres pour effectuer des comparaisons sans danger serait également bien d'avoir dans cette sous-classe.
Jon Coombs
7
Groovy fait un peu plus facile avec l' opérateur de sécurité de la navigation ( de groovy.codehaus.org/... ), ?.. Cela se transformerait nullString1?.equals(nullString2);en une déclaration entièrement nulle. Cependant, cela n'aide pas si vous avez validString?.equals(nullString);- cela lève toujours une exception.
Charles Wood
5
Méthodes courtes pour comparer des chaînes Nullable en Java: stackoverflow.com/questions/11271554/…
Vadzim
5
@JonCoombs Java prend en charge le sous-classement et la création de sa propre méthode. Cependant, peu de classes sont marquées finales pour certaines raisons, String en fait partie, nous ne pouvons donc pas l'étendre. Nous pouvons créer une autre classe et y créer une classe d'utilité qui prend deux chaînes comme arguments et y implémente notre logique. Aussi pour la vérification nulle d'autres bibliothèques comme spring et apache il de bonnes collections de méthodes, on peut l'utiliser.
Panther
442

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

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

==Donne parfois des illusions de comparer les 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 machine virtuelle Java 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, une nouvelle chaîne sera créée sur le tas, et cette référence sera donnée à b, donc bsera donnée une référence sur le tas, pas dans le pool de chaînes.

Pointe maintenant avers une chaîne dans le pool de chaînes tandis que bpointe vers une chaîne sur le tas. Pour cette raison, nous obtenons:

if (a == b) ===> false.

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

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

Bien qu'il .equals()compare toujours une valeur de chaîne, il donne la valeur true 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, .equals()c'est toujours mieux.

Ganesh
la source
3
.equals () compare les deux instances mais equals est implémenté pour les comparer. Cela pourrait ou non comparer la sortie de toString.
Jacob
3
La .equals()méthode de classe d'objets @Jacob compare les instances (références / adresse) où, en tant que .equals()méthodes de classe String , est remplacée pour comparer le contenu (caractères)
Satyadev
1
Bon à souligner les différences entre le pool de chaînes et le tas Java car elles ne sont certainement pas les mêmes. Dans le pool de chaînes, Java essaie de "mettre en cache" des Stringobjets pour économiser l'empreinte mémoire car il Stringest connu pour être immuable (j'espère que je le dis correctement ici). Consultez également stackoverflow.com/questions/3052442/…
Roland
1
C'est la réponse que je cherchais.
Weezy
Quelle bonne réponse!
alwbtc
223

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

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

Clayton
la source
5
En général, je recommande fortement la bibliothèque apache commons: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)
Marcin Erbel
179

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 un grand nombre de références de chaîne et la mise en cache de ces instances peut réduire l'empreinte mémoire et augmenter les performances du programme.

Lorsque vous utilisez l'opérateur == pour la comparaison de chaînes, vous ne comparez pas le contenu de la chaîne, mais comparez en fait l'adresse mémoire. S'ils sont tous les deux égaux, cela retournera vrai et faux sinon. Alors que égal à chaîne 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 false renvoie 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. 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 en faire une partie du cache et "MyString" == new String("MyString").intern()retournera donc true.

Remarque: l'opérateur == est beaucoup plus rapide qu'égal simplement parce que vous comparez deux adresses mémoire, mais vous devez vous assurer que le code ne crée pas de nouvelles instances de chaîne dans le code. Sinon, vous rencontrerez des bugs.

Faisal Feroz
la source
147
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 equals()méthode effectue une comparaison caractère par caractère du contenu.

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

duffymo
la source
128

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 que c'est le cas parce que 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.

Uri
la source
124

Oui, ==c'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 cordes, elles seront souvent les mêmes, mais comme vous l'avez découvert, ce n'est pas toujours garanti.

cétus
la source
118

Java possède un pool de chaînes sous lequel Java gère l'allocation de mémoire pour les objets String. Voir Pools de chaînes 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 souhaitez comparer le contenu de deux objets String, vous devez remplacer la equalsméthode.

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

Example:
    stringObjectOne.equals(stringObjectTwo);

Mais attention elle 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 voir:

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
Agarwal Saurabh
la source
7
Je vois que c'est une réponse tardive à une grande question. Puis-je demander ce qu'il fournit qui n'est pas déjà mentionné dans les réponses existantes?
Mysticial
6
@Mysticial a-t-il ajouté, equalsIgnoreCasece qui pourrait être instructif pour le plus frais.
AmitG
103

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

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

De l'exemple des zachérates:

// ... 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 
pgras
la source
8
Ce n'est généralement pas une bonne idée. L'internement est relativement coûteux et peut (paradoxalement) >> augmenter << l'empreinte mémoire de vos machines virtuelles Java et augmenter les coûts de GC. Dans la plupart des cas, ces avantages l'emportent sur les avantages en termes de performances de ==la comparaison de chaînes.
Stephen C
101

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

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

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

coobird
la source
99

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

==renvoie true si les deux objets (NOT TALKING ABOUT PRIMITIVES) pointent vers la même instance d'objet. .equals()renvoie vrai si les deux objets contiennent les mêmes données equals()Versus ==en Java

Cela peut vous aider.

Matt Razza
la source
95

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

La equals()méthode vérifiera si le contenu ou les états de 2 objets sont identiques.

C'est évidemment ==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 la equals()méthode est recommandée.

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

  1. Implémentation des String.equals()premiers contrôles d'égalité de référence (à l'aide ==), et si les 2 chaînes sont identiques par référence, aucun calcul supplémentaire n'est effectué!
  2. Si les 2 références de chaîne ne sont pas identiques, String.equals()vérifiera ensuite la longueur des chaînes. C'est également une opération rapide car la Stringclasse stocke la longueur de la chaîne, pas besoin de compter les caractères ou les points de code. Si les longueurs diffèrent, aucune vérification supplémentaire 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 abrégée: tous les caractères ne seront pas comparés, si nous trouvons un caractère qui ne correspond pas (à la même position dans les 2 chaînes ), aucun autre caractère ne sera vérifié.

En fin de compte, même si nous avons la garantie que les chaînes sont des internes, l'utilisation de la equals()méthode n'est toujours pas la surcharge que l'on pourrait penser, certainement la voie recommandée. Si vous voulez une vérification efficace des références, utilisez des énumérations où la spécification et l'implémentation du langage garantissent que la même valeur d'énumération sera le même objet (par référence).

icza
la source
2
Obviously == is faster- en fait la mise en place des .equals(String)premiers contrôles ==avant toute autre chose donc je dirais que la vitesse est à peu près identique.
Razzle Shazl
2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl
82

Si vous êtes comme moi, lorsque j'ai commencé à utiliser Java, je voulais utiliser l'opérateur "==" pour tester si deux instances de String é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 didacticiel de comparaison de chaînes Java, je vais également expliquer pourquoi l'opérateur "==" ne fonctionne pas lors de la comparaison de chaînes Java.

Option 1: comparaison de chaînes Java avec la méthode equals La plupart du temps (peut-être 95% du temps), je compare des 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 examinant un exemple de comparaison de chaîne rapide avec la méthode equals, si le test suivant était exécuté, les deux 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 en majuscules ou en minuscules. Lorsque vous souhaitez tester l'égalité de vos chaînes de cette manière, sans respecter 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 un troisième moyen, moins courant, de comparer les chaînes Java, et c'est avec la méthode StringThere compareTo. Si les deux chaînes sont exactement identiques, la méthode compareTo retournera une valeur de 0 (zéro). Voici un exemple rapide de ce à quoi ressemble cette approche de comparaison de chaînes:

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 d'égalité 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 égale dans votre classe (de la même manière que le langage Java fournit ce comportement d'égalité / comparaison dans la méthode String equals).

Vous voudrez peut-être jeter un œil à ceci ==, .equals (), compareTo () et compare ()

Mohamed E. ManSour
la source
5
pour les littéraux de chaîne Comme String string1 = "foo bar"; String string2 = "foo bar"; vous pouvez directement utiliser l'opérateur == pour tester l'égalité du contenu
JAVA
1
Dans le script Google Apps, "compareTo" n'est pas possible. J'ai essayé instaed "equals" Ce fut la seule solution qui fonctionne ....
user3887038
77

Une 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()));
}

Tester:

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);
Khaled.K
la source
6
En quoi cela diffère-t-il des autres réponses? et pourquoi faire comme vous le suggérez
user151019
2
@Mark La question sur la différence entre ==et equalsa déjà été répondue par d'autres solutions, je viens de proposer une façon différente de comparer les chaînes de manière lâche
Khaled.K
77

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

Notez que la .equals()méthode appartient à la classe Object(super classe de toutes les classes). Vous devez le remplacer selon les exigences de votre 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és 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

    Motif: si vous créez un objet String à l'aide du newmot clé, un espace distinct lui est alloué sur le tas.

Aniket Thakur
la source
53

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

samkit shah
la source
15
ne pas être pointilleux, mais la equals()méthode Stringest en fait dans la Stringclasse, pas dans Object. La valeur equals()par défaut dans Objectne comparerait pas que le contenu est le même et, en fait, renvoie juste vrai lorsque la référence est la même.
Jacob Schoen
1
@JacobSchoen: Le lien ci-dessus ne fonctionne plus car GrepCode est arrêté. Voici l'alternative pour equals Implementation: [Inline Link] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Amandeep Singh
50

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

fabricioflores
la source
7
"char []" n'est pas un type de données primitif! C'est un tableau de "char". Et les tableaux ne sont pas eux-mêmes des types de données primitifs.
Christian
48

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

Exemple

Considérons deux variables de référence différentes str1et str2:

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

Si vous utilisez le equals()

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

Vous obtiendrez la sortie comme TRUEsi vous l'utilisiez ==.

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

Maintenant , vous obtiendrez la FALSEen sortie, parce que les deux str1et str2pointent à deux objets différents , même si les deux partagent le même contenu de la chaîne. C'est à cause d' new String()un nouvel objet qui est créé à chaque fois.

Rakesh KR
la source
43

L'opérateur == est toujours destiné à la comparaison de référence d'objet , tandis que la méthode String class .equals () est remplacée pour la 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)
sham.y
la source
40

Tous les objets sont garantis d'avoir une .equals()méthode puisque Object contient une méthode .equals(),, qui retourne un booléen. C'est le travail de la sous-classe de remplacer cette méthode si une définition plus précise est requise. Sans elle (c'est-à-dire en utilisant ==), seules les adresses mémoire sont vérifiées entre deux objets pour l'égalité. La chaîne remplace cette .equals()méthode et au lieu d'utiliser l'adresse mémoire, elle retourne 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 de blocs, donc une fois qu'une chaîne est créée, elle est stockée pour toujours dans un programme à la même adresse. Les cordes ne changent pas, elles sont immuables. C'est pourquoi c'est une mauvaise idée d'utiliser la concaténation de chaîne régulière si vous avez un sérieux traitement de chaîne à faire. Au lieu de cela, vous utiliseriez les StringBuilderclasses fournies. N'oubliez pas que les pointeurs de cette chaîne peuvent changer et si vous étiez intéressé de voir si deux pointeurs étaient les mêmes, ce ==serait une bonne façon de procéder. Les cordes elles-mêmes ne le font pas.

James
la source
2
"une fois qu'une chaîne est créée, elle est stockée pour toujours dans un programme à la même adresse" - C'est tout à fait faux. Seules les expressions de chaînes constantes à la compilation (impliquant éventuellement des final Stringvariables) et les chaînes que votre programme interne explicitement sont stockées dans ce que vous appelez un "pool de blocs". Tous les autres Stringobjets sont soumis à la récupération de place une fois qu'il n'y a plus de références actives à eux, comme tout autre type d'objet. De plus, bien que l'immuabilité soit nécessaire pour que l'ensemble du mécanisme d'internement fonctionne, cela n'est pas pertinent pour cela.
Ted Hopp
La comparaison de chaînes se fait soit par la méthode equals soit equalsIgnoreCase qui compare réellement le contenu de la chaîne. Mais signe == il suffit de vérifier les valeurs de référence. Pour les littéraux de chaîne du pool de chaînes, cela fonctionnera bien dans ce cas. String s1 = new String ("a"); String s2 = new String ("a"); dans ce cas, s1 == s2 est faux, mais s1.equals (s2) est vrai.
Shailendra Singh
39

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

Le ==compare les références et ne compare pas les chaînes réelles. Si vous avez créé chaque chaîne à l'aide de, 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.

AlvaroAV
la source
35

En Java, lorsque l' opérateur "==" est utilisé pour comparer 2 objets, il vérifie si les objets se réfèrent au même endroit en mémoire. En d'autres termes, il vérifie si les 2 noms d'objet sont essentiellement des références au même emplacement mémoire.

La classe Java String remplace en fait l'implémentation equals () par défaut 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, tant que la séquence réelle de caractères est égale, les deux objets sont considérés comme égaux.

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

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

Lijo
la source
1
sauf si l'un d'eux est nul, car s.equals (s2) se bloque si s est nul, ce qui entraîne l'échec de la comparaison. Bien sûr, cela ne contredit pas vraiment la réponse; c'est juste une mise en garde.
Jon Coombs
1
Non, il ne plantera pas, il lancera une exception NullPointerException, ce qui empêchera la comparaison.
Bludzee