В чем разница между == и equals () в Java?

623

Я хотел уточнить, правильно ли я это понимаю:

  • == является эталонным сравнением, т.е. оба объекта указывают на одну и ту же ячейку памяти
  • .equals() оценивает сравнение значений в объектах
brainydexter
источник
43
да, в значительной степени
Джон Кейн
9
Да, на месте Вы можете думать об этом .equals()как о значительном эквиваленте
vikingsteve
Возможный дубликат Как сравнить строки в Java?
TylerH
19
Предложение типа «оба объекта указывают на одно и то же место в памяти» является небрежным языком, что может усложнить понимание. Вы имеете в виду: «обе переменные ссылаются на один и тот же объект». Обратите внимание, что переменная не является объектом; переменная является ссылкой на объект. Объекты не «указывают» на что-либо.
Джеспер

Ответы:

626

В общем, ответ на ваш вопрос "да", но ...

  • .equals(...) будет сравнивать только то, что написано для сравнения, не больше, не меньше.
  • Если класс не переопределяет метод equals, то по умолчанию используется equals(Object o)метод ближайшего родительского класса, который переопределил этот метод.
  • Если ни один из родительских классов не предоставил переопределение, то по умолчанию используется метод из конечного родительского класса Object, и поэтому у вас остается Object#equals(Object o)метод. В соответствии с Object API это так же, как ==; то есть он возвращает true тогда и только тогда, когда обе переменные ссылаются на один и тот же объект, если их ссылки одинаковы. Таким образом, вы будете тестировать на предметное равенство, а не функциональное равенство .
  • Всегда не забывайте переопределять, hashCodeесли переопределите, equalsчтобы не «нарушить контракт». Согласно API, результат, возвращаемый hashCode()методом для двух объектов, должен быть одинаковым, если их equalsметоды показывают, что они эквивалентны. Обратное утверждение не обязательно верно.
Судно на воздушной подушке, полное угрей
источник
если ==проверяет ссылку на память, то почему я получаю это странное поведение в [this] [1] [1]: docs.google.com/document/d/… Я ожидал, что вывод будет истинным. могу очистить мои заблуждения
JPG
4
@JSK выведите значения d1 и d2, и я думаю, вы поймете, почему вы возвращаете false.
BoDidely
2
@ BoDidely, я понял это. Это было потому, что все классы-обертки неизменны.
JPG
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).<br/> Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.( docs.oracle.com/javase/7/docs/api/java/lang/… )
Абхиджит
Не связано: сегодня я поставил мета-вопрос ( meta.stackoverflow.com/questions/372795/… ) относительно хороших / эффективных / ... «автоматических» сообщений при комментировании некачественных вопросов новичка. Обратная связь, которую я получил, была в значительной степени "ты делаешь совершенно неправильные вещи". Теперь мне просто интересно, как ты на это смотришь? У вас есть «общие» сообщения в вашем колчане, или вы пишете исключительно конкретные комментарии в таких случаях?
GhostCat
107

По отношению к классу String:

В равно () метод сравнивает «значение» внутри экземпляров String (в куче) независимо от того, если две ссылки на объекты относятся к той же строки , например , или нет. Если любые две ссылки на объекты типа String ссылаются на один и тот же экземпляр String, тогда отлично! Если две ссылки на объекты ссылаются на два разных экземпляра String .. это не имеет значения. Это «значение» (то есть содержимое массива символов) внутри каждого сравниваемого экземпляра String.

С другой стороны, оператор "==" сравнивает значение двух ссылок на объекты, чтобы определить, ссылаются ли они на один и тот же экземпляр String . Если значение обеих ссылок на объекты «ссылается» на один и тот же экземпляр String, то результатом логического выражения будет «true» .. duh. Если, с другой стороны, значения обеих ссылок на объекты "ссылаются" на разные экземпляры String (даже если оба экземпляра String имеют одинаковые "значения", то есть содержимое символьных массивов каждого экземпляра String одинаково), Результатом логического выражения будет «ложь».

Как с любым объяснением, позвольте этому погрузиться.

Надеюсь, это немного прояснит ситуацию.

Жак Кольменеро
источник
1
так что для строк == ссылка равна также? т.е. работает так же, как и для других объектов?
JonnyRaa
2
(Thread некромантия, я знаю ...) Для Stringх, ==это референс равна а, да, но это , как правило , работает (как и в двух Stringс с тем же содержанием , будет , как правило , быть ==друг с другом), из - за того , как Java ручки Strings. Это не всегда, и это, безусловно, плохая практика, но это распространенная ошибка, особенно для людей с других языков.
Тонио
7
Добавить к комментарию Тонио. Stringстроить из строкового литерала будет добавлен к чему - то называется String constant pool, например , String s1 = "someString"; String s2 = "someString;"как s1и s2разделит ту же ссылку. s1 == s2вернет истину. Но если они были созданы с помощью String constructor, например, String s1 = new String("someString"); String s2 = new String("someString");тогда они не будут использовать одну и ту же ссылку. s1 == s2вернет ложь.
Гэвин
61

Существуют небольшие различия в зависимости от того, говорите ли вы о «примитивах» или «типах объектов»; то же самое можно сказать, если вы говорите о «статических» или «нестатических» членах; Вы также можете смешать все вышеперечисленное ...

Вот пример (вы можете запустить его):

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;
    }

}

Вы можете сравнить объяснения для "==" (Оператор равенства) и ".equals (...)" (метод в классе java.lang.Object) по следующим ссылкам:

Альмир Кампос
источник
2
Интересный пример. Другая точка зрения из приведенных выше ответов. Спасибо!
Андрей
1
На мой взгляд, лучший ответ, так как он яснее других полнотекстовых ответов, не теряя объяснений (если вы, конечно,
придерживаетесь
44

Разница между == и equals смутила меня некоторое время, пока я не решил поближе взглянуть на это. Многие из них говорят, что для сравнения строк следует использовать equalsа не ==. Надеюсь, в этом ответе я смогу сказать разницу.

Лучший способ ответить на этот вопрос - задать себе несколько вопросов. Итак, начнем:

Какой вывод для следующей программы:

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

если вы говорите,

false
true

Я скажу, что вы правы, но почему вы это сказали ? и если вы говорите, выход

true
false

Я скажу, что вы не правы, но я все равно буду спрашивать вас, почему вы думаете, что это правильно?

Хорошо, давайте попробуем ответить на этот вопрос:

Какой вывод для следующей программы:

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

Теперь, если вы говорите,

false
true

Я скажу, что вы не правы, но почему это не так сейчас ? правильный вывод для этой программы

true
false

Пожалуйста, сравните вышеуказанную программу и попробуйте подумать об этом.

Хорошо. Теперь это может помочь (пожалуйста, прочитайте это: напечатать адрес объекта - невозможно, но все же мы можем его использовать.)

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));

Можете ли вы просто подумать о выводе последних трех строк в коде выше: для меня ideone распечатал это ( вы можете проверить код здесь ):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

Ой! Теперь вы видите, что identityHashCode (mango) равен identityHashCode (mango2), но не равен identityHashCode (mango3)

Несмотря на то, что все строковые переменные - mango, mango2 и mango3 - имеют одинаковое значение, то есть «манго», они identityHashCode()все же не одинаковы для всех.

Теперь попробуйте раскомментировать эту строку // mango2 = "mang";и запустите ее снова, на этот раз вы увидите, что все три identityHashCode()разные. Хм, это полезный совет

мы знаем, что если hashcode(x)=Nи hashcode(y)=N=>x is equal to y

Я не уверен, как Java работает внутри, но я предполагаю, что это то, что произошло, когда я сказал:

mango = "mango";

Java создал строку, "mango"которая была указана (на которую ссылается) переменная mangoчто-то вроде этого

mango ----> "mango"

Теперь в следующей строке, когда я сказал:

mango2 = "mango";

Он фактически использовал ту же строку, "mango"которая выглядит примерно так

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

И манго, и манго2 указывают на одну и ту же ссылку. Теперь, когда я сказал

mango3 = new String("mango")

Он фактически создал совершенно новую ссылку (строку) для «манго». который выглядит примерно так,

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

mango3 ------> "mango"

и именно поэтому, когда я выставляю значения для mango == mango2, он выставляет true. и когда я выставляю значение для mango3 == mango2, оно выводится false(даже когда значения были одинаковыми).

и когда вы раскомментировали строку, // mango2 = "mang"; она фактически создала строку «mang», которая превратила наш график следующим образом:

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

Вот почему identityHashCode не одинаков для всех.

Надеюсь, это поможет вам, ребята. На самом деле, я хотел сгенерировать тестовый пример, где == не выполняется и равно () пройти. Пожалуйста, не стесняйтесь комментировать и дайте мне знать, если я не прав.

govindpatel
источник
Происходит ли mango == mango2это потому, что вы не создали mango2 новый объект String, а вместо этого просто указали ссылку "mango"?
BRT
1
неправильный пример использования String для устранения сомнений относительно == и equals; если строка не используется с new, она помещается в String Pool и всякий раз, когда одна и та же строка присваивается новой ссылке, она указывает на одну и ту же строку в пуле. Так что, вероятно, используйте некоторый пример пользовательского объекта для сравнения == и .equals ().
om252345
30

Оператор == проверяет, имеют ли две переменные одинаковые ссылки (он же указатель на адрес памяти) .

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)

Принимая во внимание, что метод equals () проверяет, относятся ли две переменные к объектам, имеющим одинаковое состояние (значения) .

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

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

Ура :-)

Моханрай Баласубраманиам
источник
1
Неправильно. if (foo == bar) это должно быть true, а не false. Будет повторно использована та же строка "adc". Протестируйте его в песочнице, он вернет true для обоих.
Джонатан Логан
2
@JohnathanLogan Я думаю, это связано с интернированием строк. Теперь я изменился на "новую строку (" abc ")". Надеюсь, что теперь не будет никаких проблем. Спасибо за информирование.
Моханрадж Баласубраманиам
13

Вам придется переопределить функцию equals (вместе с другими), чтобы использовать ее с пользовательскими классами.

Метод equals сравнивает объекты.

==Бинарный оператор сравнивает адрес памяти.

Эндрю Карр
источник
8

И ==, и .equals () ссылаются на один и тот же объект, если вы не переопределяете .equals ().

Это ваше желание, что вы хотите сделать, как только вы переопределите .equals (). Вы можете сравнить состояние вызывающего объекта с переданным состоянием объекта или просто вызвать super.equals ()

Тинтин
источник
7

==является оператором и equals()является методом .

Операторы обычно используются для сравнения примитивных типов и, следовательно ==, используются для сравнения адресов памяти, а equals()метод используется для сравнения объектов .

ayniam
источник
6
 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
Сарат Чандра
источник
Простое и лучшее объяснение
Sritam Jagadev
5

Просто помните, что .equals(...)это должно быть реализовано тем классом, который вы пытаетесь сравнить. В противном случае, нет особого смысла; версия метода для класса Object делает то же самое, что и операция сравнения: Object # equals .

Единственный раз, когда вы действительно хотите использовать оператор сравнения для объектов, это когда вы сравниваете Enums. Это связано с тем, что одновременно существует только один экземпляр значения Enum. Например, учитывая перечисление

enum FooEnum {A, B, C}

У вас никогда не будет более одного экземпляра за Aраз, и то же самое для Bи C. Это означает, что вы можете написать такой метод:

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

И у вас не будет проблем вообще.

fruchtose
источник
4

Когда вы оцениваете код, становится очень ясно, что (==) сравнивает в соответствии с адресом памяти, а equals (Object o) сравнивает hashCode () экземпляров. Вот почему сказано, что не нарушайте контракт между equals () и hashCode (), если вы не столкнетесь с неожиданностями позже.

    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
    */
Гусейн
источник
4

Вот общее правило для разницы между relational operator ==и the method .equals().

object1 == object2сравнивает, ссылаются ли объекты, на которые ссылаются object1 и object2, на одну и ту же ячейку памяти в куче .

object1.equals(object2)сравнивает значения object1 и object2 независимо от того, где они находятся в памяти .

Это можно хорошо продемонстрировать с помощью String

Сценарий 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 

Сценарий 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

Это сравнение строк может быть использовано в качестве основы для сравнения других типов объектов.

Например, если у меня есть класс Person , мне нужно определить базу критериев, по которой я буду сравнивать двух людей . Допустим, у этого класса есть переменные экземпляра роста и веса.

Таким образом, создавая объекты-личности person1 and person2и сравнивая их с помощью .equals()I, мне нужно переопределить метод equals класса person, чтобы определить, на основании каких переменных экземпляра (высоты или веса) будет выполняться сравнение.

Однако == operator will still return results based on the memory location of the two objects(person1 and person2).

Для простоты обобщения этого объекта сравнения я создал следующий тестовый класс. Экспериментируя с этими концепциями, вы обнаружите множество фактов .

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;
}

}

Результат выполнения этого класса:

is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
Таделе Айлень
источник
3

Также обратите внимание, что .equals()обычно содержит ==для тестирования, так как это первое, что вы хотели бы проверить, если вы хотите проверить, если два объекта равны.

И на ==самом деле смотрит на значения для примитивных типов, для объектов он проверяет ссылку.

базовое обеспечение главнокомандующего нато на атлантике
источник
3

Оператор == всегда сравнивается. Но в случае

метод equals ()

это зависит от реализации, если мы переопределяем метод equals, чем он сравнивает объект с базовой реализацией, указанной в переопределенном методе.

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

в приведенном выше коде и объект obj, и объект obj1 содержат одни и те же данные, но ссылка на них не одинакова, поэтому равно return false и == также. но если мы переопределить метод равно, чем

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

знать, проверить это вернет истину и ложь для того же случая, только мы переопределены

метод равных.

он сравнивает объект на основе содержимого (id) объекта

но ==

еще сравните ссылки на объект.

Сачин Джадхав
источник
3

Основное различие между == и equals ()

1) == используется для сравнения примитивов.

Например :

        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 () используется для сравнения объектов. Например :

        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
Рави Патель
источник
2

==может использоваться во многих типах объектов, но вы можете использовать Object.equalsдля любого типа, особенно для строк и маркеров карты Google.

Dearwolves
источник
2
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");
    }

    }
  }

---- вывод ----- правда ложь правда

Аамир М Меман
источник
2

Возможно, стоит добавить, что для объектов-оболочек для примитивных типов - то есть Int, Long, Double - == вернет true, если два значения равны.

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

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

В отличие от этого, если поместить вышеупомянутые два Long в два отдельных ArrayLists, equals видит их одинаковыми, но == - нет.

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.");
Elroch
источник
Объекты-обертки для примитивных типов - т.е. Integer, Long, Double == могут не возвращать true, даже если два значения равны. Это чисто зависит от кеша Wrapper. Ниже код выведет false, потому что кэш по умолчанию ограничен -128 до 127. Long a = 128l; Long b = 128l; System.out.println(a == b);
Neetesh Bhardwaj
1

Строка бассейн (ака интернирование ) и Integer бассейн размытие разница дальше, и может позволить вам использовать== для объектов , в некоторых случаях вместо.equals

Это может дать вам большую производительность (?) За счет большей сложности.

Например:

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

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

Сложность компромисса: следующие могут вас удивить:

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

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

Я советую вам держаться подальше от такой микрооптимизации и всегда использовать .equalsдля объектов и ==для примитивов:

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

Integer i = 128;
Integer j = 128;
assert i.equals(j);
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
1

Короче говоря, ответ «да».

В Java ==оператор сравнивает два объекта, чтобы увидеть, указывают ли они на одну и ту же область памяти; в то время как .equals()метод фактически сравнивает два объекта, чтобы увидеть, имеют ли они одинаковое значение объекта.

JamesOstmann
источник
0

В принципе, == сравнивается, если два объекта имеют одну и ту же ссылку в куче, поэтому, если две ссылки не связаны с одним и тем же объектом, это сравнение будет ложным.

equals()это метод, унаследованный от Objectкласса. Этот метод по умолчанию сравнивает, если два объекта имеют одну и ту же ссылку. Это значит:

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

Однако, если вы хотите установить равенство между двумя объектами одного класса, вы должны переопределить этот метод. Также очень важно переопределить метод, hashCode()если вы переопределилиequals() .

Реализация hashCode()при установлении равенства является частью Java Object Contract. Если вы работаете с коллекциями, но не реализовали hashCode(), могут произойти странные плохие вещи:

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будет напечатан после выполнения предыдущего кода, если вы не реализовали hashCode().

lmiguelvargasf
источник
0

Поскольку Java не поддерживает перегрузку операторов, == ведет себя одинаково для каждого объекта, но метод equals () является методом, который может быть переопределен в Java, а логика сравнения объектов может быть изменена на основе бизнес-правил.

Основное различие между == и equals в Java заключается в том, что «==» используется для сравнения примитивов, а метод equals () рекомендуется для проверки равенства объектов.

Сравнение строк - это распространенный сценарий использования метода == и equals. Поскольку переопределение класса java.lang.String равно методу, он возвращает true, если два объекта String содержат одинаковое содержимое, но == будет возвращать true, только если две ссылки указывают на один и тот же объект.

Вот пример сравнения двух строк в Java на равенство с использованием метода == и equals (), который устранит некоторые сомнения:

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);

}
}
Майк Кларк
источник