Вопрос-ответ

What is the difference between == and equals() in Java?

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

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


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

  • .equals() вычисляется путем сравнения значений в объектах

Переведено автоматически
Ответ 1

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


  • .equals(...) будет сравнивать только то, что написано для сравнения, ни больше, ни меньше.

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

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

  • Всегда помните о переопределении, hashCode если вы переопределяете equals, чтобы не "разорвать контракт". Согласно API, результат, возвращаемый hashCode() методом для двух объектов, должен быть одинаковым, если их equals методы показывают, что они эквивалентны. Обратное не обязательно верно.

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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) по этим ссылкам:

Ответ 4

Разница между == и 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

И mango, и 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() прохождение. Пожалуйста, не стесняйтесь комментировать и дайте мне знать, если я ошибаюсь.

java