Почему equals() метод, когда у нас есть оператор?
Когда я вижу реализацию метода equals()
, он ничего не делает, кроме того, что делает ==
. Итак, мой вопрос заключается в том, что нужно иметь это как отдельный метод, когда у нас есть оператор ==
, который выполняет ту же работу?
Ответы
Ответ 1
Вы не можете перегрузить оператор ==
, но вы можете переопределить equals(Object)
, если вы хотите, чтобы он отличался от оператора ==
, то есть не сравнивал ссылки, а фактически сравнивал объекты (например, используя все или некоторые из их поля).
Кроме того, если вы переопределите equals(Object)
, посмотрите также hashCode()
. Эти два метода должны быть совместимы (т.е. Два объекта, равные в соответствии с equals(Object)
, должны иметь одинаковый hashCode()
), иначе будут возникать всевозможные странные ошибки (например, при добавлении объектов в набор или карту).
Ответ 2
==
сравнивает объекты ссылки и спрашивает, одинаковы ли две ссылки.
equals()
сравнивает объект содержимое и спрашивает, представляют ли объекты одну и ту же концепцию.
Ответ 3
В случае примитивов оператор ==
проверяет, совпадают ли два значения.
Если это не примитивы, он проверяет, есть ли два указателя (или ссылки), указывающие на один и тот же экземпляр объекта.
Метод equals()
выполняет пользовательскую проверку, которая находится в Object
проверке ссылки, используя ==
. Но в других классах иногда equals()
переопределяется (я не знаю, является ли это правильным причастием в прошлом). equals()
нужно проверить контент.
Итак, например:
int i0 = 34;
int i1 = 34;
int i2 = 35;
// results
i0 == i1: true
i1 == i0: true
i2 == i0: false
Но если у нас есть непримитивы
String str0 = new String("Hello man!");
String str1 = new String("Hello man!");
String str2 = new String("!nam olleH");
String str2copy = str2;
// Results
str0 == str1: false // Pointer to two different object, so == will give false
str1 == str2: false // Idem
str2 == str2copy: true // So this are two pointers to the same object
str0.equals(str1): true // This are not the same objects, but they are equal
str1 == str1: true // Again: two times a pointer to the same object
Итак, почему str0.equals(str1)
возвращает true
? Поскольку класс String имеет переопределение equals()
. И в этом методе он не проверяет, равны ли они, выполняя return this == obj;
Но в этом методе есть полная проверка. Я не знаю, какой метод они используют для сравнения двух строк, но вот два возможных способа:
- Создавая из двух строк хэш-код и проверяем, равны ли они (
int == int
)
- Проверка символа по символу, если они одинаковы.
Поэтому я надеюсь, что теперь это ясно.
Ответ 4
Существует очень важное различие между ними.
"==" сравнивает экземпляры объектов. Аналогично используется значение по умолчанию equals(). Пожалуйста, запустите и проанализируйте следующий пример кода:
public class Person{
String name;
public Person(String name){
this.name = name;
}
//overriding equals
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( name == null ) {
if( other.name != null )
return false;
} else if( !name.equals( other.name ) )
return false;
return true;
}
}
...
...
Person john1 = new Person("John");
Person john2 = new Person("John");
System.out.println("john1 == john2:" + (john1 == john2));
System.out.println("john1.equals(john2):" + john1.equals(john2));
Как вы можете видеть, "==" вернет false (объекты представляют собой два разных экземпляра Person), тогда как equals вернет true (потому что мы определили, что 2 человека равны, если они имеют одинаковое имя)
Ответ 5
Оператор == используется для сравнения ссылок.
Метод equals() определяется по определению объекта.
Dog d =new Dog();
Collar c =new Collar("Red");
d.setCollar(c);
Dog d2=new Dog();
Collar c2=new Collar("Red");
d2.setCollar(c2);
d2.getCollar() ==d.getCollar()
вернет false, указав, что у двух собак есть два разных объекта воротника (предметы). Они не используют один и тот же воротник.
d2.getCollar().equals(d.getCollar())
возвращает true, если Collar определяется как [Collar одинаковы, если цвет ошейника одинаковый]
у двух собак одинаковый цветной ошейник.
class Collar{
String color="";
public Collar(String p0){
this.color=p0;
}
boolean equals(Object c){
Collar other=(Collar)c;
return this.color.equals(other.getColor());
}
public String getColor(){
return this.color;
}
}
Ответ 6
Это сделано, чтобы сделать это возможным:
String s1 = new String("foo");
String s2 = new String("foo");
System.out.println(s1 == s2); // false?! Different references!
System.out.println(s1.equals(s2)); // true
Если вы проверяете источник String#equals()
, вы увидите, что он переопределил Object#equals()
соответствующим образом, чтобы сравнить друг с другом внутренний массив символов (фактическое значение). Многие другие классы также переопределяют этот метод.
Ответ 7
"string" == "string" вернет false
"string".equals( "string" ) вернет true
С o1 == o2 вы сравниваете, что объект 1 является тем же объектом, что и o2 (по ссылке)
С o1.equals(o2), в зависимости от объекта метод equals переопределяется и не реализуется с чем-то вроде "return o1 == o2"
Например, вы создаете 2 набора экземпляров
Эти два заданных объекта - это два разных объекта, вы можете добавлять в них любые элементы.
set1 == set2 всегда возвращает false
но set1.equals(set2) в конечном итоге вернет true, если set2 содержит точно такие же элементы, что и set1... и потому, что метод equals переопределяется в классе Set...
Реализация Equals для Set:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Set s = (Set) o;
if (s.size() != c.size())
return false;
return containsAll(s); // Invokes safe containsAll() above
}
Ответ 8
В java equals оператор (==) работает с данными двух переменных, если операнды имеют примитивные типы данных. Но если операнды являются объектами java, они сравнивают их с использованием ссылок, потому что у него нет способа выяснить, в каком поле или в полях объекта.
Таким образом, существует только один способ сравнения на основе пользовательских полей и который определяется в объекте путем переопределения методов equals(), поскольку оператор equals (==) не может быть переопределен в java, поскольку java не поддерживает переопределение оператора.
В качестве примера, если вы хотите сравнить Employee на основе имени, вам нужно определить его логику, переопределив метод equals в классе Employee, как показано ниже:
public class Employee {
private Integer id;
private String name;
@Override
public boolean equals(Object obj) {
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}