Почему equals() метод, когда у нас есть оператор?

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

+31
05 мая '10 в 11:34
источник поделиться
8 ответов

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

Кроме того, если вы переопределите equals(Object), посмотрите также hashCode(). Эти два метода должны быть совместимы (т.е. Два объекта, равные в соответствии с equals(Object), должны иметь одинаковый hashCode()), иначе будут возникать всевозможные странные ошибки (например, при добавлении объектов в набор или карту).

+41
05 мая '10 в 11:36
источник

== сравнивает объекты ссылки и спрашивает, одинаковы ли две ссылки.

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

+34
05 мая '10 в 11:40
источник

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

Метод 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)
  • Проверка символа по символу, если они одинаковы.

Поэтому я надеюсь, что теперь это ясно.

+18
05 мая '10 в 11:52
источник
Оператор

== используется для сравнения ссылок.
Метод 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;
    }
    }
+2
05 мая '10 в 13:50
источник

Существует очень важное различие между ними.

"==" сравнивает экземпляры объектов. Аналогично используется значение по умолчанию 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 человека равны, если они имеют одинаковое имя)

+2
05 мая '10 в 11:51
источник

Это сделано, чтобы сделать это возможным:

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() соответствующим образом, чтобы сравнить друг с другом внутренний массив символов (фактическое значение). Многие другие классы также переопределяют этот метод.

+1
05 мая '10 в 11:49
источник

"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
    }
0
05 мая '10 в 11:43
источник

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


}
0
10 нояб. '13 в 10:14
источник

Посмотрите другие вопросы по меткам или Задайте вопрос