Учитывая это:
String s1= new String("abc");
String s2= new String("abc");
String s3 ="abc";
System.out.println(s1==s3);
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
Вывод:
false
false
true
true
96354
96354
96354
Здесь ==
дает ложь для каждого объекта, но хэш-код для каждого Строкового объекта - то же. Почему это так?
==
сравнивает реальное равенство объектов (я имею в виду - обе ссылки указывают на один и тот же объект), а не их content, тогда как .equal
сравнивает содержимое (по крайней мере, для String).
String a = new String("aa");
String b = new String("aa");
a
и b
указывают на разные объекты.
Обратите внимание, что если объекты равны, то их хэш-коды должны быть одинаковыми, но если хэш-коды одинаковы, это не означает, что объекты равны.
В контракте равенства говорится, что если o1.equals (o2)
, то o1.hashCode () = = o2.hashCode ()
. В нем ничего не говорится о хэш-кодах неравных объектов. У вас может быть такой метод, как
public int hashCode()
{
return 42;
}
, и он будет выполнять контракт. Ожидается, что хэш-код будет связан со значением объекта, чтобы хеш-таблицы работали более эффективно.
Теперь, что касается того, почему ваш ==
не работает, два объекта всегда будут сравниваться по ссылке. То есть, если o1 == o2
, то o1
и o2
являются одним и тем же объектом. Это редко то, что вам нужно; обычно вы хотите увидеть вместо o1.equals (o2)
.
Когда вы используете ==
, вы сравниваете, содержат ли две переменные ссылки на один и тот же объект. Другими словами, s1 == s2
похоже на вопрос: относятся ли переменные s1
и s2
к одному и тому же объекту String? И это не так, даже если оба объекта String имеют одинаковое значение «abc».
Когда вы используете equals (), вы сравниваете значения обоих объектов. Оба объекта могут быть разными, но их значение (в данном случае «abc») одинаково, поэтому он возвращает true
.
Как вы определяете, равен ли объект другому? Решать вам. В этом случае объект String уже определяет это для вас, но, например, если вы определяете объект Person
, как узнать, равен ли человек P1 P2? Это можно сделать, переопределив equals ()
и hashCode ()
.
== сообщает вам, указывают ли две ссылки на переменные на один и тот же объект в памяти, не более того. equals ()
и hashCode ()
оба смотрят на содержимое объекта, и каждый использует свой собственный алгоритм для вычисления.