Determining whether two objects are equal, and equals hashcode contact methods

1, to consider whether two objects are the same rules in the collection are:

The first step: If hashCode () are equal, then the second step, otherwise it is not the same.

Step two: Check equals () equal to equal, or not the same

2, hashcode is calculated by a hashing algorithm hash value of the object or a variable, different objects are not the same,The same object is constant.

3, equals () is equal to, hashcode necessarily be equal

hashcode not equal, equals must not identical

4, rewriting class equals () methods will override when hashcode () method.

If you override the equals (), but does not override the hashcode () will cause the following problems .

public class ObjectClass {
    public static void main(String[] args) {
        Set<Demo1> demo1Set=new HashSet<>();
        Demo1 demo1=new Demo1(1,2);
        Demo1 demo2=new Demo1(3,4);
        Demo1 demo3=new Demo1(5,6);
        demo1Set.add(demo1);
        demo1Set.add(demo2);
        demo1Set.add(demo3);
        System.out.println(demo1Set);
        Demo1 demo4=new Demo1(1,2);
        demo1Set.add(demo4);
        System.out.println(demo1Set);
        System.out.println(demo1.hashCode());
        System.out.println(demo4.hashCode());
        System.out.println(demo1.hashCode());

    }
}

class Demo1{
    private int value;
    private int id;

    public Demo1(int value,int id){
        this.value=value;
        this.id=id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Demo1 demo1 = (Demo1) o;

        if (id != demo1.id) return false;
        if (value != demo1.value) return false;

        return true;
    }

//    @Override
//    public int hashCode() {
//        int result = value;
//        result = 31 * result + id;
//        return result;
//    }

    @Override
    public String toString() {
        return "Demo1{" +
                "value=" + value +
                ", id=" + id +
                '}';
    }
}
It will result in duplicate set of data


[Demo1{value=3, id=4}, Demo1{value=1, id=2}, Demo1{value=5, id=6}]
[Demo1{value=3, id=4}, Demo1{value=1, id=2}, Demo1{value=1, id=2},Demo1{value=5, id=6}]
2133927002
1173230247
2133927002

也就是说,在这种情况下,不重新写hashcode方法,两个对象是的hashcode值Object方法里面是不一样的。所以set集合里面就会认为是两个不同的对象,所以会都有。所以重写了equals方法必须重写hashcode方法。


实例应用:

public static boolean isAllSelected(WipPackage wipPackage, WiseNewsSession wiseNewsSession) {
    ConfigManager configManager = wiseNewsSession.getConfigManager();
    WipPackage wipPackageFrom4VS=getWipPackage4VS(wiseNewsSession, configManager);
    return wipPackageFrom4VS.equals(wipPackage);
}

比较wipPackageFrom4VS和wipPackage两个对象是否相等。显然如果不重写WipPackage的hashCode()方法

这两个对象的hashCode值是不相等的(因为是不同的对象)。那么既然两个对象的hashcode值不相等,

即使两个对象对应字段的值相等,equals()方法也一定是false。

so

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

    WipPackage that = (WipPackage) o;

    if (wisesearch != that.wisesearch) {
        return false;
    }
    if (wisesearchpro != that.wisesearchpro) {
        return false;
    }
    if (video != that.video) {
        return false;
    }
    if (cartoon != that.cartoon) {
        return false;
    }
    if (web != that.web) {
        return false;
    }
    if (ad != that.ad) {
        return false;
    }
    return wiselive == that.wiselive;
}

@Override
public int hashCode() {
    int result = (wisesearch ? 1 : 0);
    result = 31 * result + (wisesearchpro ? 1 : 0);
    result = 31 * result + (video ? 1 : 0);
    result = 31 * result + (cartoon ? 1 : 0);
    result = 31 * result + (web ? 1 : 0);
    result = 31 * result + (ad ? 1 : 0);
    result = 31 * result + (wiselive ? 1 : 0);
    return result;
}


那么另一个问题来了,怎么重写hashCode()方法和equals()方法呢?

一定要确保两个对象的字段相同,hashCode()和equals()就相同。

那么为什么要乘以31呢?

The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional. A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.


发布了159 篇原创文章 · 获赞 75 · 访问量 19万+

Guess you like

Origin blog.csdn.net/xuehuagongzi000/article/details/56688796