重写equals为什么要重写hashcode

判断两个对象是否相等,我们需要先判断hashcode,在hashcode相等的条件下,再用equals进行比较,equals返回true,两个对象才相等。如果hashcode不相等,那么我们直接认为这两个对象不相等。

我们来看下面两段代码:

@Data
public class QueryBO {

    private Boolean query1;
    private Boolean query3;
    private Boolean query2;

    @Override
    public boolean equals(Object o){
        if(this == o){
            return true;
        }
        if(o == null || getClass() != o.getClass()){
            return false;
        }
        QueryBO queryBO = (QueryBO) o;
        return Objects.equals(query3, queryBO.query3);
    }

    @Override
    public int hashCode(){
        return Objects.hash(query3);
    }
}
public class TestQueryBO1<Object> {

    public static void main(String[] args) {
        QueryBO queryBO1 = new QueryBO();
        queryBO1.setQuery1(true);
        queryBO1.setQuery2(true);
        queryBO1.setQuery3(false);

        QueryBO queryBO2 = new QueryBO();
        queryBO2.setQuery1(false);
        queryBO2.setQuery2(false);
        queryBO2.setQuery3(false);

        Set<QueryBO> set = new HashSet<>();
        set.add(queryBO1);
        set.add(queryBO2);
        System.out.println(set);

        System.out.println(queryBO1.equals(queryBO2));
    }
}

 运行结果我们可以发现是true,这是因为我么重写了equals(),如果我们不重写equals的话,queryBO1和queryBO2两个对象中的属性需要全部完全相等才会返回true。而重写equals后,equals()中值比较了q3,所以当两个对象中q3相等时,则会返回true。而因为queryBO1和queryBO2是相等的,由于set集合可以去重,导致set集合中只有一个元素。

如果我们讲equals方法中的的query3改为query2那么此时equals方法中判断就是query2,此时queryBO1和queryBO2中的query2不相等,返回flase。set集合中有两个元素。

接下来我们更改一下属性的值:

  QueryBO queryBO2 = new QueryBO();
        queryBO2.setQuery1(false);
        queryBO2.setQuery2(true);
        queryBO2.setQuery3(true);

可以看到,返回的结果是true,但是set集合中却存在两个值。虽然equals比较的q2相等,但是他们的hashcode不相等,所以两个对象是不相等的,set集合才没有进行去重。

所以在使用hashmap和hashset时,想要重写equals方法一定要重写hashcode。他们会先比较hashcode,hashcode相等,才会比较equals。如果hashcode不相等,那么就认为他们不相等。

猜你喜欢

转载自blog.csdn.net/cang_ling/article/details/131823083