zoukankan      html  css  js  c++  java
  • 学习:重写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

    符合预期。证毕。

  • 相关阅读:
    十分钟内学会:将HTML格式化为合法的XML
    十分钟内学会:根据数据库生成站点导航
    Adobe Apollo vs Joyeur Slingshot
    英语阅读推荐:你真的懂UPDATE语句吗 & 当有layout之时
    欲练 CSS ,必先宫 IE
    英语阅读推荐:海明威写作技巧 & UpdatePanel为何失灵
    英语阅读推荐:在AJAX中制作自定义验证服务 & 优秀网站的5个因素
    Code is Configuration
    十分钟内学会:自动识别GB2312与UTF8编码的文件
    学习 Ruby on Rails 真的很爽!
  • 原文地址:https://www.cnblogs.com/anrainie/p/2473196.html
Copyright © 2011-2022 走看看