美文网首页
为何重写equals方法必须重写hashCode方法,如何重写h

为何重写equals方法必须重写hashCode方法,如何重写h

作者: carlwu_186 | 来源:发表于2022-10-11 22:33 被阅读0次

    一旦重写了equals方法,就一定要重写hashCode方法。

    hashCode方法的约定:

    1. 一个对象多次调用它的hashCode方法,应当返回相同的integer(哈希值)。
    2. 两个对象如果通过equals方法判定为相等,那么就应当返回相同integer。相等对象必然导致相等hashCode。
    3. 两个地址值不相等的对象调用hashCode方法不要求返回不相等的integer,但是要求拥有两个不相等integer的对象必须是不同对象。不相等hashCode必然是不相等对象导致。

    在HashMap、HashTable中,put操作是先通过对象的hashCode取模运算后找到存储位置的,如果位置不存在就直接插入,如果存在,就要判定equals方法返回值是否为true,为true说明两个对象字面量是相等的,就覆盖插入。如果为false,说明发生了hash冲突。

    重写hashCode方法的目标是:不相等的对象尽可能有不同的hashCode,而且必须满足的一个通用约定是:相等的对象必须具有相同的hashCode。

    如果重写了equals方法不去重写hashCode方法,就会导致一种现象:相同的对象有不相等的hashCode,在HashMap机制下就会发生混乱。

    重写hashCode方法的示例:

    public class HashCodeTest {
    
        private String dishCode;
        private boolean weighing;
        private String categoryCode;
        private boolean currentPrice;
        private boolean discountable;
        private int stopSell;
        private int soldOut;
        private boolean deal = false;
        private List<DealGroup> dealGroupList;
     
        ...
        get、set方法
        ...
     
        @Override
        public int hashCode() {
            int result = dishCode != null ? dishCode.hashCode() : 0;
            result = 31 * result +soldOut;
            result = 31 * result +stopSell;
            result = 31 * result + (currentPrice ? 1 : 0);
            result = 31 * result + (weighing ? 1 : 0);
            result = 31 * result + (categoryCode != null ? categoryCode.hashCode() : 0);
            result = 31 * result + (dealGroupList != null ? dealGroupList.hashCode() : 0);
            return result;
        }
     }
    

    这里面为啥用个31来计算,而且很多人都是这么写的,这是因为31是个神奇的数字,任何数n*31都可以被jvm优化为(n<<5)-n,移位和减法的操作效率比乘法的操作效率高很多!
    31对虚拟机的识别非常友好,对于虚拟机来说31 = 2^5 - 1

    相关文章

      网友评论

          本文标题:为何重写equals方法必须重写hashCode方法,如何重写h

          本文链接:https://www.haomeiwen.com/subject/wlyxzrtx.html