Comment puis-je 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 bug, j'en ai changé un en .equals() à la place, et il a corrigé le bug.

est-ce que == est mauvais? Quand faut-il et doit-il pas être utilisé? Quelle est la différence?

727
demandé sur Nathan H 2009-02-05 02:17:07

23 réponses

== tests de référence pour l'égalité (qu'ils sont le même objet).

.equals() tests de valeur pour l'égalité (si elles sont logiquement "égalité").

objets.equals() vérifie null avant d'appeler .equals() si vous n'avez pas à (disponible à compter du JDK7, également disponible en Goyave ).

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

par conséquent, si vous voulez tester si deux chaînes ont la même valeur, vous aurez probablement besoin d'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 presque toujours voulez utiliser Objects.equals() . Dans le rares situation où l'on savoir vous avez affaire à internés les chaînes, vous peut utiliser == .

à Partir de JLS 3.10.5. Littéraux De Chaîne :

de plus, une chaîne littérale fait toujours référence à la même instance de la classe String . C'est parce que les chaînes littérales - ou, plus généralement, les chaînes qui sont les valeurs des expressions constantes ( §15.28 ) - sont " internés "de manière à 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 .

5070
répondu Aaron Maenpaa 2018-07-12 13:27:59

== test object references, .equals() test the string values.

parfois, il semble que == compare des valeurs, parce que Java fait des trucs dans les coulisses pour s'assurer que des chaînes 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 attention aux nuls!

== poignées null les chaînes sont fines, mais appeler .equals() à partir d'une chaîne nulle causera 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 nul, 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 pour null (de Java 7):

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

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

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

parfois == donne des illusions de comparer des valeurs de chaîne, comme dans les cas suivants:

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

c'est parce que lorsque vous créez une chaîne de caractères littérale, la JVM recherche d'abord cette chaîne de caractères littérale dans la réserve de caractères, et si elle trouve une correspondance, cette même référence sera donnée à la nouvelle chaîne de caractères. De ce fait, nous obtenez de l':

(a==b) ===> true

                       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 nouvelle chaîne sera créée sur le tas, et cette référence sera donnée à b , de sorte que b sera donnée une référence sur le tas, pas dans le pool de chaînes.

maintenant a indique un Corde dans le bassin de cordes tandis que b pointe une corde sur le tas. À cause de cela nous obtenons:

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

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

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

alors que .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
répondu 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
répondu 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 changer la chaîne originale. Ceci 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 l'opérateur == pour la comparaison des chaînes de caractères, vous ne comparez pas le contenu de la chaîne, mais comparent en fait l'adresse mémoire. S'ils sont tous les deux égaux, il retournera vrai et faux autrement. While equals in string compare the string contents.

donc la question Est si toutes les chaînes sont mises en cache dans le système, comment se fait-il que == retourne false alors que equals retourne true? Eh bien, c'est possible. Si vous faites 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 false.

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

Note: == l'opérateur est beaucoup plus rapide que égal juste 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
répondu 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 des références; la méthode equals() fait une comparaison caractère par caractère du contenu.

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

134
répondu 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 que c'est le cas parce que Java conserve une sorte de table littérale (ce qu'il fait), mais qui n'est pas toujours le cas. Certaines cordes sont chargées de différentes façons, construites à partir d'autres cordes, etc., donc vous ne devez jamais supposer que deux chaînes identiques sont stockées dans le même endroit.

égale fait la comparaison réelle pour vous.

115
répondu Uri 2017-11-19 08:16:08

Oui, == est mauvais pour la comparaison de Chaînes de caractères (les objets vraiment, sauf si vous savez qu'ils sont canonique). == ne fait que comparer les références des objets. .equals() des tests pour l'égalité. Pour les cordes, souvent ils seront les mêmes, mais comme vous l'avez découvert, ce n'est pas garanti toujours.

110
répondu cletus 2014-12-17 08:28:55

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

lorsque vous cochez (comparez) deux objets à l'aide de l'opérateur == , il compare l'égalité d'adresse dans le pool de cordes. Si les deux objets String ont les mêmes références d'adresse, alors il retourne true , sinon false . Mais si vous voulez comparer le contenu de deux objets String alors vous devez surcharger la méthode equals .

equals est en fait la méthode de la classe objet, mais elle est écrasé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, il respecte le cas de la corde. Si vous voulez comparer non sensible à la casse, alors vous devez choisir 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
répondu 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 des pointeurs (localisation de l'objet en mémoire).

== retourne true si les deux objets (ne parlant pas de PRIMITIVES) pointent vers la même instance. .equals() retourne true si les deux objets contiennent les mêmes données equals() Versus == en Java

Qui peut vous aider.

92
répondu Matt Razza 2014-12-17 08:30:43

== compare les références d'objets en Java , et ce n'est pas une exception pour les objets String .

pour comparer le contenu réel des objets (y compris String ), on doit utiliser la equals méthode .

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 la machine virtuelle Java a plusieurs points de référence vers la même instance de String . On ne devrait 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
répondu 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 cordes non-littérales.

De zacherates exemple:

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

si vous intern la chaîne non-littérale égalité est true

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

== effectue un référence contrôle d'égalité, si les 2 objets (chaînes dans ce cas) se réfèrent au même objet dans la mémoire.

la méthode equals() permet de vérifier si le contents ou le states de 2 objets sont les mêmes.

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

L'utilisation de la méthode equals() est certainement recommandée.

ne vous inquiétez pas pour la performance. Certaines choses à encourager l'utilisation de String.equals() :

  1. mise en œuvre de String.equals() premières vérifications de 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 le 2 les références de chaîne ne sont pas les mêmes, String.equals() vérifiera ensuite la longueur des chaînes. C'est aussi une opération rapide parce que la classe String stocke la longueur de la chaîne, pas besoin de compter les caractères ou les points de code. Si les longueurs diffèrent, aucun autre contrôle n'est effectué, nous savons qu'elles ne peuvent pas être égales.
  3. ce N'est que si nous sommes arrivés jusqu'ici que le contenu des 2 chaînes sera réellement comparé, et ce sera une comparaison courte main: pas tous les caractères sera comparé, 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 cordes sont des internes, l'utilisation de la méthode equals() n'est toujours pas que les frais généraux que l'on pourrait penser, certainement la voie recommandée. Si vous souhaitez un contrôle de référence efficace, puis utiliser enums où il est garanti par la spécification de la langue et la mise en œuvre que la même valeur d'enum sera le même objet (par référence).

87
répondu icza 2015-08-11 06:40:30

si vous êtes comme moi, quand J'ai commencé à utiliser Java, j'ai voulu 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 vous montrer plusieurs façons de comparer correctement les chaînes Java, en commençant par l'approche que j'utilise la plupart du temps. A la fin de ce tutoriel de comparaison de chaînes Java, je vais aussi discuter pourquoi l'opérateur "= = " ne fonctionne pas quand en comparant les cordes de Java.

Option 1: Comparaison des 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 equal de la classe Java String, comme ceci:

if (string1.equals(string2))

cette chaîne égale la méthode regarde 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.

regardez une chaîne rapide exemple de comparaison avec la méthode equals, si le test suivant était exécuté, les deux chaînes ne seraient pas considérées comme égales parce que 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 des chaînes avec l'equalsIgnoreCase méthode

dans certains tests de comparaison de chaînes, vous voudrez ignorer si les chaînes sont en majuscules ou en minuscules. Lorsque vous voulez tester 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 des chaînes Java avec la méthode compareTo

il y a aussi une troisième façon, moins courante de comparez les chaînes Java, et c'est avec la méthode compareTo de la classe String. Si les deux chaînes sont exactement les mêmes, la méthode compareTo renvoie la valeur 0 (zéro). Voici un exemple rapide de ce à quoi ressemble cette approche de comparaison de chaîne de caractères:

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 égale dans la classe D'objet Java de base. Chaque fois que vous créez vos propres objets et vous si vous voulez fournir un moyen de voir si deux instances de votre objet sont "égales", vous devez outrepasser (et implémenter) cette méthode equals dans votre classe (de la même manière que le langage Java fournit ce comportement égalité/comparaison dans la méthode String equals).

Vous voudrez peut-être avoir un coup d'oeil à cette ==, .equals(), compareTo(), et compare()

78
répondu 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()));
}

essai:

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
répondu Khaled.K 2016-09-09 11:55:23

le == contrôle de l'opérateur 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).

noter que la méthode .equals() appartient à la classe Object (super classe de toutes les classes). Vous devez l'annuler selon les exigences de votre classe, mais pour String il est déjà implémenté, et il 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érales de cordes créées sans null sont stockées dans le pool de cordes dans la zone permgen de heap. Donc S1 et s2 pointent vers le même objet dans la piscine.

  • 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 attribué sur le tas.

67
répondu Aniket Thakur 2018-02-08 19:30:03

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

49
répondu samkit shah 2014-03-04 20:19:10

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

47
répondu fabricioflores 2014-12-17 08:31:39

si la méthode equals() est présente dans la classe java.lang.Object , et qu'elle est censée 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érer deux variables de référence différentes, str1 et 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 TRUE si vous utilisez == .

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

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

42
répondu Rakesh KR 2018-02-08 19:33:11

opérateur = = signifie toujours comparaison de référence d'objet , alors que la classe de chaîne de caractères .equals() la méthode est remplacée par contenu "de comparaison 151950920" :

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
répondu sham.y 2018-02-08 19:20:12

Tous les objets sont garantis d'avoir un .equals() méthode depuis l'Objet contient une méthode, .equals() , qui renvoie un booléen. La tâche de la sous-classe consiste à outrepasser cette méthode si une définition plus précise est nécessaire. Sans elle (c'est-à-dire en utilisant == ), seules les adresses mémoire sont vérifiées pour l'égalité entre deux objets. La chaîne de caractères 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 égalité.

une note clé est que les chaînes de caractères sont stockées dans un pool unique de sorte qu'une fois qu'une chaîne de caractères 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 une quantité sérieuse de traitement de chaîne à faire. Vous utiliserez plutôt les classes StringBuilder fournies. Rappelez-vous les pointeurs de cette chaîne peut changer et si vous étiez intéressé pour voir si deux les pointeurs étaient les mêmes == serait un bon chemin à faire. Les ficelles elles-mêmes ne le font pas.

36
répondu James 2018-02-08 19:12:44

vous pouvez également utiliser la méthode compareTo() pour comparer deux chaînes. Si le résultat compareTo est 0, alors les deux cordes sont égales, sinon les cordes 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 en utilisant new String(somestring).intern() , alors vous pouvez utiliser l'opérateur == pour comparer deux chaînes, sinon les méthodes equals() ou compareTo ne peuvent être utilisées.

36
répondu AlvaroAV 2018-02-08 19:21:07

en Java, lorsque le "==" l'opérateur est utilisé pour comparer 2 objets, il vérifie pour voir si les objets se réfèrent au même endroit dans la 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 l'emporte en fait sur l'implémentation par défaut des equals() dans la classe objet – et elle l'emporte sur la méthode de sorte qu'elle ne vérifie que les valeurs des chaînes, et non leurs localisations en mémoire. Cela signifie que si vous appelez la méthode equals () pour comparer 2 objets String, alors aussi longtemps que la séquence réelle des caractères est égale, les deux objets sont considérés égaux.

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

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

34
répondu Lijo 2014-08-04 00:48:38