学习:重写hashCode()方法的必要性-阿里云开发者社区

开发者社区> anrainie> 正文

学习:重写hashCode()方法的必要性

简介: 当一个类有可能会和其他类发生比较的时候,我们会重写equals方法,但大多数情况下,都忽略了重写hashCode方法。 这里说一下重写hashCode的必要性。 当我们使用HashSet或者HashMap的时候,在比对value|key是否存在时,会调用hashCode方法。
+关注继续查看

当一个类有可能会和其他类发生比较的时候,我们会重写equals方法,但大多数情况下,都忽略了重写hashCode方法。

这里说一下重写hashCode的必要性。

当我们使用HashSet或者HashMap的时候,在比对value|key是否存在时,会调用hashCode方法。

注意,hashSet的contains方法其实是依赖于HashMap的containsKey方法的。

我们来看下containsKey方法的实现:

  public boolean containsKey(java.lang.Object paramObject)
  {
    return (getEntry(paramObject) != null);
  }

  final Entry<K, V> getEntry(java.lang.Object paramObject)
  {
    int i = (paramObject == null) ? 0 : hash(paramObject.hashCode());
    Entry localEntry = this.table[indexFor(i, this.table.length)];
    for (; localEntry != null; 
      localEntry = localEntry.next)
    {
      if (localEntry.hash == i) { java.lang.Object localObject;
        if (((localObject = localEntry.key) == paramObject) || ((paramObject != null) && (paramObject.equals(localObject))))
        {
          return localEntry; } }
    }
    return null;
  }

 

由上面代码即可知,hashCode是重要的判断依据,没有重写hashCode,equals表现相等的两个类,它们的hashCode并不相等。

所以会导致containsKey方法返回false,测试代码如下:

包含HashCode的类:

package hashset.and.hashcode;

public class ClassWithHashCode {
    public int i;

    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (o instanceof ClassWithHashCode) {
            ClassWithHashCode code = (ClassWithHashCode) o;
            return code.i == i;
        }
        return false;
    }

    public int hashCode() {
        return i * 17 + 37;
    }
}

没有重写hasCode的类:

package hashset.and.hashcode;

public class ClassWithoutHashCode {
    public int i;

    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (o instanceof ClassWithoutHashCode) {
            ClassWithoutHashCode code = (ClassWithoutHashCode) o;
            return code.i == i;
        }
        return false;
    }
}

 

测试类:

package hashset.and.hashcode;

import java.util.HashSet;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ClassWithHashCode c1 = new ClassWithHashCode();
        ClassWithHashCode c2 = new ClassWithHashCode();
        c1.i = 0;
        c2.i = 0;

        HashSet<ClassWithHashCode> set = new HashSet<ClassWithHashCode>();
        set.add(c1);
        System.out.println(set.contains(c2));

        ClassWithoutHashCode co1 = new ClassWithoutHashCode();
        ClassWithoutHashCode co2 = new ClassWithoutHashCode();
        co1.i = 0;
        co2.i = 0;

        HashSet<ClassWithoutHashCode> set1 = new HashSet<ClassWithoutHashCode>();
        set1.add(co1);
        System.out.println(set.contains(co2));
    }
}

 

 

执行的结果为:

true
false

 

符合预期。证毕。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《Photoshop修色圣典(第5版)》—第1章1.7节此测试的重要性
<span style='letter-spacing:1px'>本节书摘来自异步社区《Photoshop修色圣典(第5版)》一书中的第1章1.7节此测试的重要性,作者【美】Dan Margulis,更多章节内容可以访问云栖社区“异步社区”公众号查看。</span>
1236 0
简单易用的编译器--Nano|学习笔记
快速学习简单易用的编译器--Nano
17 0
强大的编辑器--vim|学习笔记
快速学习强大的编辑器--vim
24 0
PHP7 学习笔记(三)关于PHP7如何安装调试工具Xdebug扩展以及Zephir的问题
安装这个扩展是由于Zephir 编译不能始终通过,迫不得已啊,使用Zephir写扩展,总是出现以下错误: www@ubuntu1:~/phalcon-zephir/$ sudo zephir build Segmentation fault (core dumped) 去官方问问,由于php c...
1548 0
学习分布式不得不会的ACP理论
2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想。2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP。
2319 0
+关注
anrainie
Eclipse RCP开发者。
113
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载