Классический вопрос на собеседовании по Java: разница между equals, == и hashcode()

Java

==:

Сравнение значений используется для примитивных типов, а сравнение ссылок — для ссылочных типов.

	/**
     * == 的比较
     */
    @Test
    public void testOne(){
        int a = 200;
        int b = 200;
        Integer c = 200;
        Integer d = 200;
        //值比较
        System.out.println(a == b);//同基本类型同值比较:true
        //引用类型比较
        System.out.println(c == d);//false
    }

equals:

equals — это метод исходного класса Object, то есть метод equals есть у всех объектов. == сначала сравнивается, а затем оценивается). Следует ли выполнять сравнение значений), так что в целом это сравнение значений, Примечание: базовые типы не могут использовать сравнение равенства, но используют ==, потому что базовые типы не имеют метода равенства .

Давайте взглянем на метод equals, переопределяемый Obeject:

//Object:
public boolean equals(Object obj) {
        return (this == obj);
    }
    
 //Integer :
 //先判断是否为同一类型,不是直接false,是的话在进行值比较
public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    
//String:
//先比较地址,然后判断是否为同一类型,不是直接false,是的话在进行值比较
public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

Сравнение равных

class Cat{
    String name = "cat";
}
class Dog{
    String name = "dog";
}
________________________________________________________________________
	/**
     * euqals 比较
     */
    @Test
    public void testTwo(){
        int a = 200;
        int b = 200;
        Integer c = 300;
        Integer d = 300;
        Cat cat = new Cat();
        Dog dog = new Dog();
        System.out.println(c.equals(a));//false
        System.out.println(c.equals(d));//true
        //System.out.println(a.equals(cat));//基本类型不能使用equals比较,而是用==,因为基本类型没有equals方法
    }

hashcode():

Hashcode() также является методом объекта, это нативный метод, реализованный на языке C/C++, и значение адреса возвращаемого объекта вызывается java. Но многие классы в JDK переписывают hashcode(). Например, если логическое значение означает «истина», хеш-значение равно 1231, а если оно означает «ложь», хеш-значение равно 1237.

	//Object:
	public native int hashCode();
	
	//Integer直接返回值
    public int hashCode() {
        return Integer.hashCode(value);
    }
    public static int hashCode(int value) {
        return value;
    }
    
	//String 返回此字符串的哈希码。
	public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

Простое использование хэш-кода():

class Cat{
    String name = "cat";
}
class Dog{
    String name = "dog";
}
---------------------------------------------------------------------
	@Test
    public void testThree(){
        Cat cat = new Cat();
        Dog dog = new Dog();
        System.out.println(cat.hashCode());//204349222
        System.out.println(dog.hashCode());//231685785
        Integer a = 200;
        Integer b = 300;
        System.out.println(a.hashCode());//200
        System.out.println(b.hashCode());//300
    }

Сравнение равных и ==, hashcode():

  1. Два объекта, равные(), равны, и их hashCode() должен быть равен.
  2. Два объекта с одинаковым hashCode() не обязательно равны их equal().

Попробуйте использовать ассоциации, чтобы запомнить приведенные выше понятия. Например, HashMap, который мы используем. Его структура выглядит следующим образом:

hashcode() равны, то они имеют одинаковую позицию корзины, на данный момент это как Entry1 и Entry2, но равные Entry1 и Entry2 не обязательно хотят ждать, это другой пример Entry1=abc, Entry2=abc, тогда они равны, но Entry1=abc, Entry2=def , то они не равны.equals равны, то они находятся в одном столбце, это означает, что положение ведра такое же, тогда .hashCode() должен быть таким же