Java基础-理解散列与散列码

1.从HashMap说起

我们知道Map以键值对的形式来存储数据。有一点值得说明的是,如果要使用我们自己的类作为键,我们必须同时重写hashCode() 和 equals()两个方法。HashMap使用equals方法来判断当前的键是否与表中的键相同。equals()方法需要满足以下5个条件

  • 自反性 x.equals(x) 一定返回true
  • 对称性 x.equals(y)返回true,则y.equals(x) 也返回true
  • 传递性 x.equals(y)返回true,y.equals(z)返回true,则x.equals(y)返回true
  • 一致性 如果对象中的信息没有改变,x.equals(y)要么一直返回true,要么一直返回false
  • 对任何不是null的x,想x.equals(null)一定返回false
2.散列

散列的价值在于速度。

假如键没有按照一定的顺序进行保存,那么查询的时候就只能按照顺序进行线性查询,然而,线性查询是最慢的查询方式。所以,将键值按照一定的顺序排序,并且使用二分查找能购有效的提升速度。散列在此之上,更近一步,他将键保存在数组中(数组的查询速度最快),用数组来表示键的信息,但是由于Map的容量是可变的,而数组的容量是不变的。要解决这个问题,数组中存的并不是键本身,而是键对象生成的一个数字,将其作为数组的下标,这个数字就是散列码。

而这种办法所产生的问题就是下标重复。而我们的解决办法就是配合equals来确定键值。

查询的过程首先就是计算散列码,然后用散列码来查询函数(下标),通常,我们的数组中保存的是值的list,因此,我们计算出散列码之后,通过下表取到的对应部分的list,然后通过equals就可以快速找到键值。

3.HashCode

hashCode函数是用来生成散列码的,我们看看Integer的计算方式(ps:我们自己的对象我们要选择自己的方式)

    public static int hashCode(int value) {
        return value;
    }

这里不在多说,我们自己的类有自己的散列码实现就好。

4. 以HashMap的get方法来说明
    public V get(Object key) {
        if (key == null) {
            HashMapEntry<K, V> e = entryForNullKey;
            return e == null ? null : e.value;
        }

        int hash = Collections.secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                e != null; e = e.next) {
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
                return e.value;
            }
        }
        return null;
    }
  • int hash = Collections.secondaryHash(key); 计算出散列码
  • HashMapEntry
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
                return e.value;
            }
  • 若地址相同,返回值,
  • 若hash值相等且equals返回true,返回值
5.总结

不知道各位朋友看了这篇之后是否理解了散列和散列码。还是原来就懂,被我这么一顿bb,不懂了!!!

  • 11
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值