zoukankan      html  css  js  c++  java
  • HashCode的作用

    Hash

    先用一张图看下什么是Hash

    Hash是散列的意思,就是把任意长度的输入,通过散列算法变换成固定长度的输出,该输出就是散列值。关于散列值,有以下几个关键结论:

    1、如果散列表中存在和散列原始输入K相等的记录,那么K必定在f(K)的存储位置上

    2、不同关键字经过散列算法变换后可能得到同一个散列地址,这种现象称为碰撞

    3、如果两个Hash值不同(前提是同一Hash算法),那么这两个Hash值对应的原始输入必定不同

    HashCode

    然后讲下什么是HashCode,总结几个关键点:

    1、HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的

    2、如果两个对象equals相等,那么这两个对象的HashCode一定也相同

    3、如果对象的equals方法被重写,那么对象的HashCode方法也尽量重写

    4、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置

    为什么重写Object的equals(Object obj)方法尽量要重写Object的hashCode()方法

    public class HashCodeClass
    {
        private String str0;
        private double dou0;
        private int       int0;
        
        public boolean equals(Object obj)
        {
            if (obj instanceof HashCodeClass)
            {
                HashCodeClass hcc = (HashCodeClass)obj;
                if (hcc.str0.equals(this.str0) && 
                    hcc.dou0 == this.dou0 &&
                    hcc.int0 == this.int0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
    public class TestMain
    {
        public static void main(String[] args)
        {
            System.out.println(new HashCodeClass().hashCode());
            System.out.println(new HashCodeClass().hashCode());
            System.out.println(new HashCodeClass().hashCode());
            System.out.println(new HashCodeClass().hashCode());
            System.out.println(new HashCodeClass().hashCode());
            System.out.println(new HashCodeClass().hashCode());
        }
    }

    打印出来的值是:

    1901116749
    1807500377
    355165777
    1414159026
    1569228633
    778966024

    两个HashCodeClass类equals的前提是两个HashCodeClass的str0、dou0、int0分别相等。

    现在我的HashCodeClass都没有赋初值,那么这6个HashCodeClass应该是全部equals的。如果以HashSet为例,HashSet内部的HashMap的table本身的大小是16,那么6个HashCode对16取模分别为13、9、1、2、9、8。第一个放入table[13]的位置、第二个放入table[9]的位置、第三个放入table[1]的位置。。。但是明明是全部equals的6个HashCodeClass,怎么能这么做呢?HashSet本身要求的就是equals的对象不重复,现在6个equals的对象在集合中却有5份(因为有两个计算出来的模都是9)。

    那么我们该怎么做呢?重写hashCode方法,根据str0、dou0、int0搞一个算法生成一个尽量唯一的hashCode,这样就保证了str0、dou0、int0都相等的两个HashCodeClass它们的HashCode是相等的,这就是重写equals方法必须尽量要重写hashCode方法的原因。

  • 相关阅读:
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Navicat查询哪些表有指定字段名
  • 原文地址:https://www.cnblogs.com/IvySue/p/7490631.html
Copyright © 2011-2022 走看看