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

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

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

Я прав в своем понимании ?

23 ответов


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

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

относительно класса String:

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

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

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

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


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

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

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

}

вы можете сравнить объяснения для "= = "(оператор равенства) и".равняется.(..)" (метод в Java.ленг.Класс объекта) по этим ссылкам:


разница между == и равными смутила меня на некоторое время, пока я не решил взглянуть на нее поближе. Многие из них говорят, что для сравнения строки, вы должны использовать 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

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

mango3 = new String("mango")

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

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

mango3 ------> "mango"

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

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

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

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

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


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

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)

Ура :-)


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

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

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


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

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


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

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

enum FooEnum {A, B, C}

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

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

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


 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

== Это оператор и equals() это метод.

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


= = оператор:

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

The .метод equals ()

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

Для Примера:

http://goo.gl/Sa3q5Y


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

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


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

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


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

основная разница между == и 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

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


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

метод 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 объект содержит одни и те же данные, но ссылка не одинакова, поэтому равняется возвращению false и == также. но если мы переопределяем метод equals чем

 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 для того же случая, только мы переопределили

метод equals .

Он сравнивает объект по основному содержанию (id) объекта

а ==

по-прежнему сравнивать ссылки на объект.


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

    }
  }

----выходной----- истинный ложный правда


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

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

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

для контраста, помещая вышеупомянутые два Лонга в два отдельных 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.");

на строковый пул (он же интерн) и целое число, бассейн размыть разницу дальше, и может позволить вам использовать == для объектов в некоторых случаях вместо .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);

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

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

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().


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

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

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


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

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

сравнение строк является общим сценарием использования как ==, так и equals метод. начиная с java.ленг.Переопределение класса String равно методу, It возвращает true, если два строковых объекта содержат одинаковое содержимое, но == будет только возвращать значение 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);

}
}