web-dev-qa-db-fra.com

Quelle est la difference entre == et equals () en Java?

Je voulais clarifier si je comprends bien ceci:

  • == -> est une comparaison de référence, c'est-à-dire que les deux objets pointent vers le même emplacement mémoire
  • .equals() -> évalue la comparaison des valeurs dans les objets

Suis-je correct dans ma compréhension?

537
brainydexter

En général, la réponse à votre question est "oui", mais ...

  • .equals(...) comparera uniquement ce qui est écrit, ni plus ni moins.
  • Si une classe ne substitue pas la méthode equals, elle utilisera par défaut la méthode equals(Object o) de la classe parente la plus proche qui a remplacé cette méthode. 
  • Si aucune classe parent n'a fourni de remplacement, la méthode de la classe parent ultime, Object, est utilisée par défaut. Il ne vous reste donc que la méthode Object#equals(Object o). Selon l’API d’objet, c’est la même chose que ==; c'est-à-dire qu'il renvoie true if et seulement si les deux variables font référence au même objet, si leurs références sont identiques. Ainsi, vous allez tester l'égalité d'objet et non l'égalité fonctionnelle .
  • Rappelez-vous toujours de remplacer hashCode si vous remplacez equals afin de ne pas "rompre le contrat". Selon l'API, le résultat renvoyé par la méthode hashCode() pour deux objets doit être identique si leurs méthodes equals indiquent qu'elles sont équivalentes. L'inverse est pas nécessairement vrai. 
542

En ce qui concerne la classe String:

Equals () method compare la "valeur" dans les occurrences de String (sur le tas) indépendamment du fait que les deux références d'objet fassent référence à la même instance de String ou non. Si deux références d'objet de type String font référence à la même instance String, alors c'est génial! Si les deux références d'objet font référence à deux occurrences String différentes, cela ne fait aucune différence. C'est la "valeur" (c'est-à-dire: le contenu du tableau de caractères) à l'intérieur de chaque instance de chaîne comparée.

D'autre part, "==" operator compare la valeur de deux références d'objet pour voir si elles font référence à la même instance String. Si la valeur des deux références d'objet "fait référence à" la même instance String, le résultat de l'expression booléenne serait "true" .. duh. Si, en revanche, la valeur des deux références d'objet "fait référence à" instances de chaîne différentes (même si les deux instances de chaîne ont des "valeurs" identiques, le contenu des tableaux de caractères de chaque instance de chaîne est le même) le résultat de l'expression booléenne serait "faux".

Comme pour toute explication, laissez-le s'enfoncer.

J'espère que cela clarifie un peu les choses.

94

Il y a quelques petites différences selon que vous parliez de "primitives" ou de "types d'objet"; la même chose peut être dite si vous parlez de membres "statiques" ou "non statiques"; vous pouvez également mélanger tout ce qui précède ...

Voici un exemple (vous pouvez l'exécuter):

public final class MyEqualityTest
{
    public static void main( String args[] )
    {
        String s1 = new String( "Test" );
        String s2 = new String( "Test" );

        System.out.println( "\n1 - PRIMITIVES ");
        System.out.println( s1 == s2 ); // false
        System.out.println( s1.equals( s2 )); // true

        A a1 = new A();
        A a2 = new A();

        System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
        System.out.println( a1 == a2 ); // false
        System.out.println( a1.s == a2.s ); // true
        System.out.println( a1.s.equals( a2.s ) ); // true

        B b1 = new B();
        B b2 = new B();

        System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
        System.out.println( b1 == b2 ); // false
        System.out.println( b1.getS() == b2.getS() ); // false
        System.out.println( b1.getS().equals( b2.getS() ) ); // true
    }
}

final class A
{
    // static
    public static String s;
    A()
    {
        this.s = new String( "aTest" );
    }
}

final class B
{
    private String s;
    B()
    {
        this.s = new String( "aTest" );
    }

    public String getS()
    {
        return s;
    }

}

Vous pouvez comparer les explications de "==" (opérateur d'égalité) et de ".equals (...)" (méthode de la classe Java.lang.Object) via les liens suivants:

52
Almir Campos

La différence entre == et les égaux m'a troublé jusqu'à ce que je décide de l'examiner de plus près ... Beaucoup d'entre eux disent que pour comparer une chaîne, vous devez utiliser equals et non ==. J'espère que dans cette réponse, je pourrai faire la différence.

La meilleure façon de répondre à cette question sera de vous poser quelques questions. alors commençons:

Quel est le résultat pour le programme ci-dessous:

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

si tu le dis, 

false
true

Je dirai que vous êtes à droite mais pourquoi avez-vous dit que? Et si vous dites que le résultat est,

true
false

Je dirai que vous êtes faux mais je vous demanderai quand même pourquoi vous pensez que c'est vrai?

Ok, essayons de répondre à celle-ci:

Quel est le résultat pour le programme ci-dessous:

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

Maintenant si vous dites,

false
true

Je dirai que vous êtes faux mais pourquoi est-il faux maintenant? Le bon résultat pour ce programme est

true
false

S'il vous plaît comparer le programme ci-dessus et essayer d'y penser.

D'accord. Maintenant ceci pourrait aider (lisez ceci: affichez l'adresse de l'objet - pas possible mais nous pouvons quand même l'utiliser.)

String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);

System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));

pouvez-vous simplement essayer de penser à la sortie des trois dernières lignes du code ci-dessus: pour moi ideone l’a imprimé ( vous pouvez vérifier le code ici ):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

Oh! Maintenant, vous voyez que identityHashCode (mango) est égal à identityHashCode (mango2), mais il n'est pas égal à identityHashCode (mango3)

Même si toutes les variables de chaîne - mangue, mango2 et mango3 - ont la valeur same, qui est "mango", identityHashCode() n'est toujours pas la même pour tous.

Essayez maintenant de décommenter cette ligne // mango2 = "mang"; et de la réexécuter cette fois-ci. Les trois noms identityHashCode() sont différents . Hmm, c'est un indice utile.

nous savons que si hashcode(x)=N et hashcode(y)=N => x is equal to y

Je ne sais pas comment Java fonctionne en interne, mais je suppose que c'est ce qui s'est passé quand j'ai dit:

mango = "mango";

Java a créé une chaîne "mango" qui a été pointée (référencée) par la variable mango quelque chose comme ceci

mango ----> "mango"

Maintenant dans la ligne suivante quand j'ai dit:

mango2 = "mango";

Il a en fait réutilisé la même chaîne "mango" qui ressemble à ceci

mango ----> "mango" <---- mango2

Mangue et mangue2 pointant toutes deux vers la même référence. Maintenant, quand je dis 

mango3 = new String("mango")

Il a en fait créé une toute nouvelle référence (chaîne) pour "mangue". qui ressemble à ça,

mango -----> "mango" <------ mango2

mango3 ------> "mango"

et c’est pourquoi, lorsque j’ai publié les valeurs pour mango == mango2, il a sorti true. et quand je mets la valeur pour mango3 == mango2, elle sortira false (même si les valeurs étaient les mêmes).

et quand vous avez annulé la ligne // mango2 = "mang";, il a en fait créé une chaîne "mang" qui a transformé notre graphique comme suit:

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

C'est pourquoi identityHashCode n'est pas la même pour tous.

En espérant que cela vous aide les gars… .. En fait, je voulais générer un scénario de test où == échoue et = (…) passe. S'il vous plaît n'hésitez pas à commenter et à me laisser savoir si je me trompe.

40
govindpatel

L'opérateur == teste si deux variables ont les mêmes références (Pointeur sur une adresse mémoire)}.

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (The objects are not the same)

bar = foo;

if(foo==bar)
// True (Now the objects are the same)

Tandis que la méthode equals () teste si deux variables font référence à des objets qui ont le même état (valeurs).

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

À votre santé :-)

29
dheeran

Vous devrez remplacer la fonction equals (avec d'autres) pour l'utiliser avec des classes personnalisées.

La méthode equals compare les objets.

L'opérateur binaire == compare les adresses mémoire.

12
Andrew Carr

== et .equals () font tous deux référence au même objet si vous ne remplacez pas .equals (). 

C'est votre souhait ce que vous voulez faire une fois que vous substituez .equals (). Vous pouvez comparer l'état de l'objet appelant avec l'état passé dans l'objet ou vous pouvez simplement appeler super.equals ()

6
tintin

== est un opérateur et equals() est une méthode.

Les opérateurs sont généralement utilisés pour les comparaisons de type primitive. Ainsi, == est utilisé pour la comparaison d'adresses en mémoire et la méthode equals() est utilisée pour comparer objets

5
ayniam

Rappelez-vous simplement que .equals(...) doit être implémenté par la classe que vous essayez de comparer. Sinon, il n'y a pas beaucoup de point; la version de la méthode pour la classe Object fait la même chose que l'opération de comparaison: Object # equals .

La seule fois où vous souhaitez vraiment utiliser l'opérateur de comparaison pour les objets est lorsque vous comparez des énumérations. En effet, il n'y a qu'une seule instance d'une valeur Enum à la fois. Par exemple, étant donné l'énumération

enum FooEnum {A, B, C}

Vous n'aurez jamais plus d'une instance de A à la fois et identique pour B et C. Cela signifie que vous pouvez réellement écrire une méthode comme ceci:

public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

Et vous n'aurez aucun problème.

5
fruchtose
 String w1 ="Sarat";
 String w2 ="Sarat";
 String w3 = new String("Sarat");

 System.out.println(w1.hashCode());   //3254818
 System.out.println(w2.hashCode());   //3254818
 System.out.println(w3.hashCode());   //3254818

 System.out.println(System.identityHashCode(w1)); //prints 705927765
 System.out.println(System.identityHashCode(w2)); //prints 705927765
 System.out.println(System.identityHashCode(w3)); //prints 366712642


 if(w1==w2)   //  (705927765==705927765)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true

 if(w2==w3)   //  (705927765==366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints false


 if(w2.equals(w3))   //  (Content of 705927765== Content of 366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true
5
Sarat Chandra

L'opérateur ==:

Le == est un opérateur relationnel en Java utilisé pour comparer deux opérandes. Il est utilisé pour déterminer si les deux opérandes sont égaux ou non. À l'aide de l'opérateur ==, vous pouvez comparer tout type de primitive tel que int, char, float et Booleans. Après comparaison, l'opérateur == renvoie une valeur booléenne. Si les deux opérandes sont égaux, l'opérateur == renvoie une valeur vraie. Cependant, si les deux opérandes ne sont pas égaux, il renvoie une valeur fausse . Lorsqu'il est utilisé avec des objets, l'opérateur == compare les deux références d'objet et détermine si elles font référence à la même instance.

La méthode .equals ()

equals () est une méthode disponible dans la classe String utilisée pour comparer deux chaînes et déterminer si elles sont égales. Cette méthode renvoie une valeur booléenne à la suite de la comparaison. Si les deux chaînes contiennent les mêmes caractères dans le même ordre, la méthode equals () renvoie true. Sinon, il retourne une valeur fausse.

4

La principale différence entre == et equals () est

1) == est utilisé pour comparer les primitives.

Par exemple : 

        String string1 = "Ravi";
        String string2 = "Ravi";
        String string3 = new String("Ravi");
        String string4 = new String("Prakash");

        System.out.println(string1 == string2); // true because same reference in string pool
        System.out.println(string1 == string3); // false

2) equals () est utilisé pour comparer des objets .Par exemple:

        System.out.println(string1.equals(string2)); // true equals() comparison of values in the objects
        System.out.println(string1.equals(string3)); // true
        System.out.println(string1.equals(string4)); // false
3
Ravi Patel

Notez également que .equals() contient normalement == pour le test, car il s’agit de la première chose à tester si vous souhaitez tester si deux objets sont égaux. 

Et == examine effectivement les valeurs des types primitifs, alors qu'il vérifie la référence des objets.

3
bfs

Lorsque vous évaluez le code, il est très clair que (==) compare en fonction de l'adresse de la mémoire, tandis qu'égal à (Object o) compare hashCode () des instances. C'est pourquoi il est dit de ne pas rompre le contrat entre equals () et hashCode () si vous ne faites pas face à des surprises plus tard. 

    String s1 = new String("ALi");
    String s2 = new String("Veli");
    String s3 = new String("ALi");

    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s3.hashCode());


    System.out.println("(s1==s2):" + (s1 == s2));
    System.out.println("(s1==s3):" + (s1 == s3));


    System.out.println("s1.equals(s2):" + (s1.equals(s2)));
    System.out.println("s1.equal(s3):" + (s1.equals(s3)));


    /*Output 
    96670     
    3615852
    96670
    (s1==s2):false
    (s1==s3):false
    s1.equals(s2):false
    s1.equal(s3):true
    */
3
huseyin
public class StringPool {

public static void main(String[] args) {

    String s1 = "Cat";// will create reference in string pool of heap memory
    String s2 = "Cat";
    String s3 = new String("Cat");//will create a object in heap memory

    // Using == will give us true because same reference in string pool

    if (s1 == s2) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using == with reference and Object will give us False

    if (s1 == s3) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using .equals method which refers to value

    if (s1.equals(s3)) {
        System.out.println("true");
    } else {
        System.out.println("False");
    }

    }
  }

----Sortie----- vrai faux vrai

2
Aamir Meman

Voici un aperçu général de la règle pour la différence entre relational operator == et the method .equals().

_object1 == object2_ compare si les objets référencés par object1 et object2 font référence à t le même emplacement mémoire dans Heap .

object1.equals(object2) compare les valeurs de object1 et object2 indépendamment de leur emplacement en mémoire .

Cela peut être bien démontré en utilisant String

Scénario 1

_ public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = new String("Hello");
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

 }



The result is
      is str1 == str2 ? false
      is str1.equals(str2) ? true 
_

Scénario 2

_public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = "Hello";
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

}

The result is 
  is str1 == str2 ? true
  is str1.equals(str2) ? true
_

Cette comparaison de chaîne pourrait être utilisée comme base pour comparer d'autres types d'objet.

Par exemple, si j'ai une classe Person , je dois définir la base de critères sur laquelle je vais comparer deux personnes . Disons que cette classe de personnes a des variables d'instance de taille et de poids.

Donc, créer des objets personne _person1 and person2_ et pour comparer ces deux objets à l’aide de la .equals(), il est nécessaire de redéfinir la méthode de la classe de personnes poids) la comparaison sera.

Cependant, la == operator will still return results based on the memory location of the two objects(person1 and person2).

Pour faciliter la généralisation de cette comparaison d'objet personne, j'ai créé la classe de test suivante. Les expérimentations sur ces concepts révéleront des tonnes de faits .

_package com.tadtab.CS5044;

public class Person {

private double height;
private double weight;

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}


@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(height);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}

@Override
/**
 * This method uses the height as a means of comparing person objects.
 * NOTE: weight is not part of the comparison criteria
 */
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
        return false;
    return true;
}

public static void main(String[] args) {

    Person person1 = new Person();
    person1.setHeight(5.50);
    person1.setWeight(140.00);

    Person person2 = new Person();
    person2.setHeight(5.70);
    person2.setWeight(160.00);

    Person person3 = new Person();
    person3 = person2;

    Person person4 = new Person();
    person4.setHeight(5.70);

    Person person5 = new Person();
    person5.setWeight(160.00);

    System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
    System.out.println("is person2 == person3 ? " + (person2 == person3)); // true 
    //this is because perosn3 and person to refer to the one person object in memory. They are aliases;
    System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;

    System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;

    // even if the person2 and person5 have the same weight, they are not equal.
    // it is because their height is different
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}

}
_

Le résultat de cette exécution de classe est:

_is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
_
2
tadtab

Il peut être intéressant d’ajouter que, pour les objets wrapper des types primitifs - Int, Long, Double - == retournera la valeur true si les deux valeurs sont égales.

Long a = 10L;
Long b = 10L;

if (a == b) {
    System.out.println("Wrapped primitives behave like values");
}

En revanche, en plaçant les deux longs précédents dans deux ArrayLists distincts, les égaux les voient comme identiques, mais pas les ==.

ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();

c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is true.");
2
Elroch

== peut être utilisé dans de nombreux types d'objet, mais vous pouvez utiliser Object.equals pour tout type, en particulier les chaînes et les marqueurs Google Map.

2
Dearwolves

L'opérateur == toujours la référence est comparée. Mais en cas de 

méthode equals ()

cela dépend de l'implémentation si nous sommes surchargés de la méthode equals que cela compare l'objet sur la base de l'implémentation donnée dans la méthode surchargée 

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//fasle
      obj==obj1 // fasle
    }
 }

dans le code ci-dessus, obj et l'objet obj1 contiennent les mêmes données, mais la référence n'est pas la même, donc est égal à false et == également .

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }
    public boolean equals(Object obj)
    {
       A a1=(A)obj;
      return this.id==a1.id;
    }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//true
      obj==obj1 // fasle
    }
 }

savoir vérifier, il retournera vrai et faux pour le même cas que nous avons remplacé 

méthode equals.

il compare objet sur la base du contenu (id) de l'objet

mais ==

toujours comparer les références d'objet.

2
Sachin Jadhav

Étant donné que Java ne prend pas en charge la surcharge des opérateurs, == se comporte de manière identique Pour chaque objet, à l'exception de la méthode equals (), qui peut être remplacée dans Java et la logique de comparaison des objets peuvent être modifiées en fonction des règles commerciales. .

La principale différence entre == et les égaux en Java est que "==" est utilisé pour les primitives compare, tandis que la méthode equals () est recommandée pour vérifier. Égalité des objets.

La comparaison de chaînes est un scénario courant utilisant à la fois la méthode == et la méthode equals. Depuis que la classe Java.lang.String substitue la méthode equals, It Retournera true si deux objets String contiennent le même contenu mais == sera Retournera seulement true si deux références pointent sur le même objet.

Voici un exemple de comparaison de l'égalité de deux chaînes en Java à l'aide de la méthode == et de la méthode equals (), qui dissipera certains doutes:

public class TEstT{

    public static void main(String[] args) {

String text1 = new String("Apple");
String text2 = new String("Apple");

//since two strings are different object result should be false
boolean result = text1 == text2;
System.out.println("Comparing two strings with == operator: " + result);

//since strings contains same content , equals() should return true
result = text1.equals(text2);
System.out.println("Comparing two Strings with same content using equals method: " + result);

text2 = text1;
//since both text2 and text1d reference variable are pointing to same object
//"==" should return true
result = (text1 == text2);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);

}
}
0
Mike Clark

En bref, la réponse est "oui".

En Java, l'opérateur == compare les deux objets pour voir s'ils pointent vers le même emplacement mémoire. tandis que la méthode .equals() compare en réalité les deux objets pour voir s’ils ont la même valeur d’objet.

0
JamesOstmann

Fondamentalement, == compare si deux objets ont la même référence sur le tas. Ainsi, à moins que deux références soient liées au même objet, cette comparaison sera fausse.

equals() est une méthode héritée deObjectclass. Cette méthode par défaut compare si deux objets ont la même référence. Ça veut dire:

object1.equals(object2) <=> object1 == object2

Toutefois, si vous souhaitez établir une égalité entre deux objets de la même classe, vous devez redéfinir cette méthode. Il est également très important de remplacer la méthode hashCode() si vous avez surchargé equals().

Implémentez hashCode() lorsque l'établissement de l'égalité fait partie du contrat d'objet Java. Si vous travaillez avec des collections et que vous n'avez pas implémenté hashCode(), Strange Bad Things pourrait se produire:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

null sera imprimé après l'exécution du code précédent si vous n'avez pas implémenté hashCode().

0
lmiguelvargasf

Le Pool de chaînes (aka interning ) et Integer pool estompent davantage la différence et peuvent vous permettre d'utiliser == pour les objets dans certains cas au lieu de .equals

Cela peut vous donner une meilleure performance (?), Au prix d'une plus grande complexité.

Par exemple.:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

Compromis de complexité: ce qui suit peut vous surprendre:

assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

Je vous conseille de rester à l’écart de cette micro-optimisation et toujours utilisez .equals pour les objets et == pour les primitives:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);