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

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

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

Правильно ли я в своем понимании?

+556
источник поделиться
25 ответов

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

  • .equals(...) будет сравнивать только то, что написано для сравнения, не больше, не меньше.
  • Если класс не переопределяет метод equals, то по умолчанию используется метод equals(Object o) ближайшего родительского класса, который переопределил этот метод.
  • Если родительские классы не предоставили переопределение, то по умолчанию используется метод из конечного родительского класса Object и поэтому вы остаетесь с методом Object#equals(Object o). В Object API это то же самое, что и ==; то есть он возвращает true тогда и только тогда, когда обе переменные относятся к одному и тому же объекту, если их ссылки одно и то же. Таким образом, вы будете тестировать на равенство объектов, а не на функциональное равенство.
  • Всегда помните, чтобы переопределить hashCode если вы переопределяете equals чтобы не "разорвать контракт". Согласно API, результат, возвращаемый методом hashCode() для двух объектов, должен быть таким же, если их методы equals показывают, что они эквивалентны. Обратное утверждение не обязательно верно.
+567
источник

Что касается класса String:

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

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

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

Надеюсь, это немного облегчит ситуацию.

+98
источник
другие ответы

Связанные вопросы


Похожие вопросы

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

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

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

}

Вы можете сравнить объяснения для "==" (Equality Operator) и ".equals(...)" (метод в классе java.lang.Object) через эти ссылки:

+55
источник

Разница между == и 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 - имеют одинаковое значение, то есть "mango", 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, это mango == mango2 true. и когда я mango3 == mango2 значение для mango3 == mango2, оно mango3 == mango2 false (даже когда значения были одинаковыми).

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

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

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

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

+41
источник

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

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)

Приветствия: -)

+29
источник

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

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

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

+12
источник

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

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

+7
источник

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

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

enum FooEnum {A, B, C}

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

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

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

+5
источник

== - оператор, а equals() - метод.

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

+5
источник

Оператор ==:

== - это реляционный оператор в Java, который используется для сравнения двух операндов. Он используется для определения, равны ли два операнда или нет. Используя оператор ==, вы можете сравнить любой тип примитива, такой как int, char, float и Booleans. После сравнения оператор == возвращает логическое значение. Если два операнда равны, оператор == возвращает истинное значение. Однако, если два операнда не равны, он возвращает ложное значение. При использовании с объектами оператор == сравнивает две ссылки на объекты и определяет, ссылаются ли они на один и тот же экземпляр.

Метод .equals()

equals() - это метод, доступный в классе String, который используется для сравнения двух строк и определения, равны ли они. Этот метод возвращает логическое значение в результате сравнения. Если две строки содержат одинаковые символы в одинаковом порядке, метод equals() возвращает true. В противном случае он возвращает ложное значение.

+5
источник
 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
источник

"==" фактически сравнивают две ссылки на объекты, чтобы увидеть, указывают ли они на один и тот же объект.

"равно" , что является "глубоким сравнением", которое сравнивает фактические значения строк.

+4
источник

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

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

+3
источник

Когда вы оцениваете код, очень ясно, что (==) сравнивается в соответствии с адресом памяти, а 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
    */
+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
+3
источник

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

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

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

Чтобы контрастировать, поставив два вышеупомянутых Longs в два отдельных 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.");
+2
источник

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

+2
источник
Оператор

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

метод 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
    }
 }

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

равен методу.

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

но ==

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

+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
источник

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

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

Сравнение строк - общий сценарий использования метода == и equals. Поскольку класс java.lang.String переопределяет метод equals, он возвращает 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);

}
}
0
источник

String pool (aka interning) и 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);
0
источник

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

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

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

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

Реализация hashCode() при установлении равенства является частью Контракта объектов Java. Если вы работаете с коллекциями, а вы не реализовали 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().

0
источник

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

Основное различие между методом.equals() и оператором == заключается в том, что один метод, а другой - оператор.

Мы можем использовать операторы == для сравнения ссылочного сравнения (сравнения адресов) и.equals() для сравнения содержимого. Простыми словами == проверяет, указывают ли оба объекта на одну и ту же ячейку памяти, тогда как.equals() оценивает сравнение значений в объектах. Если класс не переопределяет метод equals, то по умолчанию он использует метод equals (Object o) ближайшего родительского класса, который переопределил этот метод. См. Подробности

0
источник

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

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

0
источник

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

object1 == object2 сравнивает, 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, мне нужно определить базу критериев, по которой я буду сравнивать двух людей. Допустим, у этого класса есть переменные экземпляра роста и веса.

Поэтому при создании объектов person person1 and person2 и для их сравнения с использованием .equals() мне необходимо переопределить метод 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
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос