面试笔记:equals、hashcode、==

2018-03-23  本文已影响0人  denkbug
Java相关规定

Java对于eqauls方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同
(2)如果两个对象的hashCode相同,它们并不一定相同

当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。

不遵循规定产生的后果

如果你自定义了一个对象,重写了equals方法,但没有重写hashcode方法,那么此时的equals为true但是hashcode为false,就会产生奇怪的现象。

package com.denk;

import java.util.HashSet;
import java.util.Set;

/**
 * @author: denk
 * desc:
 * date: 2018/3/23
 */
public class Person {
    public int age;
    public String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        Person p = (Person) obj;
        return p.age == this.age && p.name.equals(this.name);
        //return super.equals(obj);
    }

    public static void main(String[] args) {
        Person a = new Person(1, "mike");
        Person b = new Person(1, "mike");
        System.out.println(a.hashCode() + "###" + b.hashCode());
        System.out.println(a.equals(b));//打印为true

        Set<Person> set = new HashSet<>();
        set.add(a);
        set.add(b);
        System.out.println(set.size());//打印2
    }
}

如上代码,重写了equals但没有重写hashcode,造成的结果就是在使用equals比较时两个对象是相等的。奇怪的现象产生了,因为set的size是2,说明两个相等的对象被添加到set中了。
所以在重写equals时一定要遵循Java的规定,同时重写hashcode

遵循规定同时重写equals和hashcode
package com.denk;

import java.util.HashSet;
import java.util.Set;

/**
 * @author: denk
 * desc:
 * date: 2018/3/23
 */
public class Person {
    public int age;
    public String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public int hashCode() {
        return 31 * this.age;
        //return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        Person p = (Person) obj;
        return p.age == this.age && p.name.equals(this.name);
        //return super.equals(obj);
    }

    public static void main(String[] args) {
        Person a = new Person(1, "mike");
        Person b = new Person(1, "mike");
        System.out.println(a.hashCode() + "###" + b.hashCode());
        System.out.println(a.equals(b));//打印为true

        Set<Person> set = new HashSet<>();
        set.add(a);
        set.add(b);//将会添加失败
        System.out.println(set.size());//打印1
    }
}
上一篇下一篇

猜你喜欢

热点阅读