• HashTable源码简单介绍


    首先是继承了字典类Dictionary,
    这说明HashTable的一些找位置的实现与Dictionary有关,

    看一看数据结构,是一个entry数组,
    Entry,这个不陌生,先看一下它的结构吧,这样更加能理解,
    每个节点包括hash值,key,value,还有下一个节点,这像不像c++中的链表呢?
    是的,Entry的每一个元素都是一个链表,
    看一张图,表示hashtable中的存储结构,弄清楚这个都比较好理解了,一开始我就是这里没看清楚,还导致对一些方法产生了误解,(ps:其实这么多中间最不能让我理解的就是contains的双重循环,这是我当初的问题,好蠢)


    另一个重点是hash的计算,
    -----------分割线-----------
    说到底这里的hashcode是object的,具体还得看继承它的类是怎么实现的,

    回到主线,
    容量啊,加载因子啊,就不说了,看个这个,hashseed,
    目的是让hash值的重复几率变小,

    这个hashSeed的初始化要借用到一个值,capacity(最大容量),
    这,就触及到我的知识盲区了,不过看这流程是随机出的一个值,不过这个值不是平常意义上的随机,是有一定的条件的,
    在做hash时要考虑hash冲突,以前在学c++数据结构时有一些像开放地址法这类的解决办法,估计这里是它的一种解决办法,通过这种hashseed和hashcode结合,

    接下来是HashTable的初始化了,有4种方式,不过总体来说,最终都是调用了第一种,
    (1)给出容量和负载因子
    (2)给一个容量,默认负载因子
    (3)默认
    (4)用map初始化

    HashTable中的hash,
    这个是最后的计算,hashSeed ^ k.hashCode()

    hashhTable有一个hashCode是这样的,
    不过不要误会,这是map的hashcode,可不是key的,

    想来想去还是先要看put方法,在这之前,先弄清楚 int index = (hash & 0x7FFFFFFF) % tab.length;
    网上看到一个回答,感觉不错,
    总共是32位,1位符号位,

    put方法,
    计算hash值,计算index,从index链表找,如果找到了(不仅要hash值相同,key也要一样),则改旧的值,然后返回了,
    如果没找到,则看要不要要扩容了,
    如果count要大于(int)(capacity * loadFactor).)了,扩容:rehash,算新的index;否则不扩容,
    最后都要放入新的Entry,在index链表(这个index已经不是最初的那个了)插入,目测是开头插入了,

    扩容的rehash,
    算出了新的capacity,然后建了一个新的Entry数组,boolean rehash是看要不要随机出新的hashseed,接下来是复制old到new的Entry了,复制过程中(双重循环哦),如果rehash的true的话,那么每个元素的key的hash要重新计算了,index也要重算喽,然后在index插入,

    有入就有出,remove,
    删除这里要考虑一个问题,要判断是第几次找到,如果第一下就找到是要删除的,直接把index链表值替换掉,如果不是第一次就找到哦,那么就要通过pre来指向e.next,从而过滤掉e,

    哦,对了,注意哦,hashTable是线程安全的,很多方法都使用了synchronized同步,
    从尾部向头部找,这个是找值的方法,注意双重循环,大数组,小链表!

    这个是找key的方法,
    首先根据传进来的key算出hash值,然后根据这个hash值算出index,从这个index链表开始向后面找,

    得到value,


    hashTable主要的内容已经在这了,需要先把这些基础的搞懂,再去考虑一些效率啊,逻辑啊~


    @Arya0624
  • 相关阅读:
    Java 中的悲观锁和乐观锁的实现
    乐观锁和悲观锁的区别
    理解RESTful架构
    修复Linux下curl等无法使用 Let's Encrypt 证书
    呕心沥血 AR VR 好资源分享
    linux服务器出现大量TIME_WAIT的解决方法
    Ubuntu系统 无法删除 redis-server
    Python Flask jsonify a Decimal Error
    微信小程序 订阅消息 对接详细记录
    FTP时显示500 Illegal PORT command的解决
  • 原文地址:https://www.cnblogs.com/Arry10/p/7731744.html
Copyright © 2020-2023  润新知