[Java] Hashtable 源码简要分析
Hashtable /HashMap / LinkedHashMap 概述
Hashtable 特点
Hashtable 源码简要分析
- class Entry<K,V> // Entry<K,V>是槽中的元素,可做链表,解决散列冲突。
- {
- int hash; // 即key.hashCode()
- K key;
- V value;
- Entry<K,V> next; // 用来实现链表结构。同一链表中的key的hash是相同的。
- protected Entry(int hash, K key, V value, Entry<K,V> next) {
- this.hash=hash;this.key=key;this.value=value;this.next=next;
- }
- }
- public class Hashtable<K,V>
- {
- Entry[] table; // 槽数组,也称桶数组。
- int count; // table中实际存放的Entry数量。
- int threshold; // 当table数量超过该阈值后,进行reash。(该值为 capacity * loadFactor)
- float loadFactor; // 加载因子,默认是0.75f。
- public Hashtable(int initialCapacity/*默认是11*/, float loadFactor) {
- if(initialCapacity==0) initialCapacity=1;
- this.locadFactor = locadFactor;
- table = new Entry[initialCapacity];
- threshold = (int)(initialCapacity * locadFactor);
- }
- // put(): 若key存在,返回旧value;若key不存在,返回null。
- public synchronized V put(K key,V value) {
- // 检查key是否已经存在,若存在则覆盖已经存在value,并返回被覆盖的value。
- Entry tab[] = table;
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % tab.length; // 存储槽位索引。
- for(Entry<K,V> e = tab[index]; e!=null; e=e.next ) { // 在冲突链表中寻找
- if( (e.hash == hash ) && e.key.equals(key) ) {
- V old = e.value;
- e.value = value; // 新value覆盖旧value
- return old;
- }
- }
- // 是否需要rehash
- if(count >= threshold){
- rehash();
- tab = table; // rehash完毕后,修正tab指针指向新的Entry[]
- index = (hash & 0x7FFFFFFF) % tab.length; // 重新计算Slot的index
- }
- // 存储到槽位,如果有冲突,新来的元素被放到了链表前面。
- Entry<K,V> e = tab[index]; // 旧有Entry
- tab[index] = new Entry<>(hash,key,value,e/* 旧有Entry成为了新增Entry的next */);
- count ++;
- return null;
- }
- // rehash(): 再次hash。当Entry[]的实际存储数量占分配容量的约75%时,扩容并且重新计算各个对象的槽位
- static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 ;
- protected void rehash() {
- int oldCapacity = table.length;
- Entry[] oldMap = table;
- int newCapacity = (oldCapacity << 1) + 1; // 2倍+1
- Entry[] newMap = new Entry[newCapacity];
- threshold = (int)(newCapacity * loadFactor);
- table = newMap;
- for( int i=oldCapacity; i-- >0;){ // i的取值范围为 [oldCapacity-1,0]
- for (Entry<K,V> old = oldMap[i]; old!=null;){ // 遍历旧Entry[]
- Entry<K,V> e = old;
- int index = (e.hash & 0x7FFFFFFF) % newCapacity; // 重新计算各个元素在新Entry[]中的槽位index。
- e.next = newMap[index]; // 已经存在槽位中的Entry放到当前元素的next中
- newMap[index]=e; // 放到槽位中
- old = old.next;
- }
- }
- }
- }
References
[Java] Hashtable 源码简要分析的更多相关文章
- [Java] HashMap 源码简要分析
特性 * 允许null作为key/value. * 不保证按照插入的顺序输出.使用hash构造的映射一般来讲是无序的. * 非线程安全. * 内部原理与Hashtable类似. 源码简要分析 pu ...
- [Java] LinkedHashMap 源码简要分析
特点 * 各个元素不仅仅按照HashMap的结构存储,而且每个元素包含了before/after指针,通过一个头元素header,形成一个双向循环链表.使用循环链表,保存了元素插入的顺序. * 可设置 ...
- RxJava && Agera 从源码简要分析基本调用流程(2)
版权声明:本文由晋中望原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/124 来源:腾云阁 https://www.qclo ...
- Activity源码简要分析总结
Activity源码简要分析总结 摘自参考书籍,只列一下结论: 1. Activity的顶层View是DecorView,而我们在onCreate()方法中通过setContentView()设置的V ...
- Java - HashTable源码分析
java提高篇(二五)-----HashTable 在java中与有两个类都提供了一个多种用途的hashTable机制,他们都可以将可以key和value结合起来构成键值对通过put(key,valu ...
- RxJava && Agera 从源码简要分析基本调用流程(1)
版权声明:本文由晋中望原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/123 来源:腾云阁 https://www.qclo ...
- Java Hashtable 源码(JDK8)
记录了HashMap也来看看Hashtable吧,最近打算换份实习,所以想看看书回顾一下,不然就快记不得了.....囧啊囧啊,记性太差怎么破??? Hashtable里面的一些变量: Entry< ...
- Elasticsearch之client源码简要分析
问题 让我们带着问题去学习,效率会更高 1 es集群只配置一个节点,client是否能够自动发现集群中的所有节点?是如何发现的? 2 es client如何做到负载均衡? 3 一个es node ...
- Redis源码简要分析
转载请注明来源:https://www.cnblogs.com/hookjc/ 把所有服务端文件列出来,并且标示出其作用:adlist.c //双向链表ae.c //事件驱动ae_epoll.c // ...
随机推荐
- python接口自动化测试十二:对返回的json的简单操作
# 1.requests里面自带解析器转字典 print(r.json()) print(type(r.json())) # 取出json中的'result_sk_temp'字段 # {"r ...
- python 全栈开发,Day135(爬虫系列之第2章-BS和Xpath模块)
一.BeautifulSoup 1. 简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: ''' Beautiful Soup提供一些简单 ...
- python 全栈开发,Day6(is,小数据池,编码转换)
一.is a = 100 b = 100 print(a == b) print(a is b) 执行输出: TrueTrue 查看内存地址,使用id函数 print(id(a)) print(id( ...
- C++传值、传引用
C++传值.传引用 C++的函数参数传递方式,可以是传值方式,也可以是传引用方式.传值的本质是:形参是实参的一份复制.传引用的本质是:形参和实参是同一个东西. 传值和传引用,对大多数常见类型都是适用的 ...
- Javascript事件设计模式(七)
一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程 ...
- Queuing HDU2604
一道递推题目 得到递推关系为 f[n]=f[n-1]+f[n-3]+f[n-4]; 用普通的枚举算法会超时 所以要用矩阵快速幂来加速 转化为矩阵即为: +1 0 1 1 F(N-1) F ...
- 6-17 看图写树 uva10562
非常好的dfs题 有很多细节 关于‘ ’ ‘0’ ’\n‘ 的处理 他们都属于isspace函数 其中 while(buf[x+2][i]=='-'&&buf[x+3][i] ...
- FZU 2150 Fire Game(双起点)【BFS】
<题目链接> 题目大意: 两个熊孩子在n*m的平地上放火玩,#表示草,两个熊孩子分别选一个#格子点火,火可以向上向下向左向右在有草的格子蔓延,点火的地方时间为0,蔓延至下一格的时间依次加一 ...
- Java开发人员必须掌握的Linux命令(三)
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 学习应该是快乐的,在这个乐园中我努力让自己能用简洁易懂(搞笑有趣)的表达来讲解知识或者技术,让学习之旅充满乐趣,这就是写博 ...
- Ubuntu python Compression requires the (missing) zlib module
描述: 在Ubuntu中安装setuptools时出现 Compression requires the (missing) zlib module 解决方法步骤: ①Ubuntu下安装zlib: ...