В чем разница между == и equals () в Java? - PullRequest
570 голосов
/ 22 сентября 2011

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

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

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

Ответы [ 23 ]

578 голосов
/ 22 сентября 2011

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

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

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

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

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

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

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

55 голосов
/ 06 марта 2014

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

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

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) по следующим ссылкам:

43 голосов
/ 05 апреля 2016

Разница между == и 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 не одинаков для всех.

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

29 голосов
/ 09 августа 2016

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

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)

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

12 голосов
/ 22 сентября 2011

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

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

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

7 голосов
/ 22 сентября 2011

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

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

5 голосов
/ 15 января 2014

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

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

5 голосов
/ 23 сентября 2011

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

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

enum FooEnum {A, B, C}

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

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

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

5 голосов
/ 29 сентября 2015

Оператор ==:

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

Метод .equals ()

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

...