美文网首页
为什么重写equals时要重写hashCode

为什么重写equals时要重写hashCode

作者: herohua | 来源:发表于2020-09-16 09:44 被阅读0次

    在每个覆盖了equals方法的类中,都必须覆盖hashCode方法。如果不这样做的话,就会违反hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这类集合包括HashMap和HashSet。

    Object规范预定:

    如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中的hashCode方法都必须产生同样的整数结果。

    因没有覆盖 hashcode而违反的该关键约定:相等的对象必须具有相等的散列码( hash code)。根据类的equals方法,两个截然不同的实例在逻辑上有可能是相等的,但是根据 Object类的 hashcode方法,它们仅仅是两个没有任何共同之处的对象。因此,对象的 hashcode方法返回两个看起来是随机的整数,而不是根据第二个约定所要求的那样,返回两个相等的整数。

    假设在 HashMap中用Phonenumber类的实例作为键:

    Map<PhoneNumber, String> m = new HashMap<>();
    m.put(new PhoneNumber(707, 867, 5309), "herohua");
    

    此时,你可能期望m.get( new PhoneNumber(707,867,5309))会返回"herohua",但它实际上返回的是null。注意,这里涉及两个 Phonenumber实例:第一个被插入 HashMap中,第二个实例与第一个相等,用于从Map中根据 Phonenumber去获取用户名字。由于Phonenumber类没有覆盖 hashcode方法,从而导致两个相等的实例具有不相等的散列码,违反了 hashcode的约定。因此,put方法把电话号码对象存放在一个散列桶(hash bucket)中,get方法却在另一个散列桶中查找这个电话号码。即使这两个实例正好被放到同一个散列桶中,get方法也必定会返回null,因为 HashMap有一项优化,可以将与每个项相关联的散列码缓存起来,如果散列码不匹配,也就不再去检验对象的等同性。

    相关文章

      网友评论

          本文标题:为什么重写equals时要重写hashCode

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