zoukankan      html  css  js  c++  java
  • 重写hashcode

    学习:重写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

  • 相关阅读:
    STL————vector的用法
    DFS,DP————N皇后问题
    DP经典问题—————(LCIS)最长公共上升子序列
    DP————LIS(最长上升子序列)和LCS(最长公共子序列)问题
    CentOS7使用firewalld打开关闭防火墙与端口
    CentOS7下安装MySQL5.7安装与配置(YUM)
    nginx + tomcat +redis 负载均衡遇到问题集锦
    centos 7 安装 tomcat
    centos 7 设置防火墙 开放指定端口
    centos 7 通过yum 安装 nginx
  • 原文地址:https://www.cnblogs.com/curry1234/p/5068627.html
Copyright © 2011-2022 走看看