`
这些年
  • 浏览: 402123 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

zy19982004--容器学习二:Hashtable源码分析

 
阅读更多

一.前言

  1. HashMap和Hashtable大部分算法是相同的,容器学习一:HashMap源码分析 对HashMap源码进行了分析,可以先阅读它。
  2. 相同的算法部分不再分析,本文主要考虑Hashtable和HashMap的不同之处。

 

二.Hashtable成员变量

Java代码  收藏代码
  1. private transient Entry[] table;  
  2.   
  3. // 等同于HashMap里面的size  
  4. private transient int count;  
  5.   
  6. private int threshold;  
  7.   
  8. private float loadFactor;  
  9.   
  10. private transient int modCount = 0;  

 

 

 

三.Hashtable构造函数

Java代码  收藏代码
  1. // DEFAULT_INITIAL_CAPACITY=11,DEFAULT_LOAD_FACTOR还是0.75  
  2. public Hashtable() {  
  3.     this(110.75f);  
  4. }  
  5.   
  6. public Hashtable(int initialCapacity, float loadFactor) {  
  7.     if (initialCapacity < 0)  
  8.         throw new IllegalArgumentException("Illegal Capacity: "  
  9.                 + initialCapacity);  
  10.     if (loadFactor <= 0 || Float.isNaN(loadFactor))  
  11.         throw new IllegalArgumentException("Illegal Load: " + loadFactor);  
  12.   
  13.     if (initialCapacity == 0)  
  14.         initialCapacity = 1;  
  15.     // 直接用initialCapacity初始化,并没有要求用2的次方指来初始化  
  16.     this.loadFactor = loadFactor;  
  17.     table = new Entry[initialCapacity];  
  18.     threshold = (int) (initialCapacity * loadFactor);  
  19. }  

 

 

四.hash算法和index算法

Java代码  收藏代码
  1. //自己拿到key的hash值  
  2. int hash = key.hashCode();  
  3. //计算index做了求模运算。  
  4. int index = (hash & 0x7FFFFFFF) % tab.length;  

 

 

五.取数据

Java代码  收藏代码
  1. public synchronized V get(Object key) {  
  2.     Entry tab[] = table;  
  3.     //Hashtable所有的方法都不接受null的key,所有的地方都是不判断就直接key.hashCode();  
  4.     int hash = key.hashCode();         
  5.     int index = (hash & 0x7FFFFFFF) % tab.length;  
  6.     for (Entry<K, V> e = tab[index]; e != null; e = e.next) {  
  7.         //同HahsMap相比没有判断e.key==key,  
  8.         //Hahstable里面,e.key.equals(key)就够了,在key不为null的前提下e.key==key是e.key.equals(key)的充分不必要条件  
  9.         if ((e.hash == hash) && e.key.equals(key)) {   
  10.             return e.value;  
  11.         }  
  12.     }  
  13.     return null;  
  14. }  

 

 

六.存数据

Java代码  收藏代码
  1. public synchronized V put(K key, V value) {  
  2.         if (value == null) {  
  3.             throw new NullPointerException();  
  4.         }  
  5.   
  6.         Entry tab[] = table;  
  7.         int hash = key.hashCode();  
  8.         int index = (hash & 0x7FFFFFFF) % tab.length;  
  9.         for (Entry<K, V> e = tab[index]; e != null; e = e.next) {  
  10.             if ((e.hash == hash) && e.key.equals(key)) {  
  11.                 V old = e.value;  
  12.                 e.value = value;  
  13.                 return old;  
  14.             }  
  15.         }  
  16.   
  17.         modCount++;  
  18.         //HashMap先加Entry再决定是否扩容,Hahstable再判断大小在加Entry  
  19.         //我还是喜欢这样比较:count + 1 >  threshold  
  20.         if (count >= threshold) {  
  21.             rehash();  
  22.   
  23.             tab = table;  
  24.             index = (hash & 0x7FFFFFFF) % tab.length;  
  25.         }  
  26.   
  27.         // Creates the new entry.  
  28.         Entry<K, V> e = tab[index];  
  29.         tab[index] = new Entry<K, V>(hash, key, value, e);  
  30.         count++;  
  31.         return null;  
  32.     }  
  33.       
  34.     protected void rehash() {  
  35.         int oldCapacity = table.length;  
  36.         Entry[] oldMap = table;  
  37.   
  38.         int newCapacity = oldCapacity * 2 + 1;  
  39.         Entry[] newMap = new Entry[newCapacity];  
  40.   
  41.         modCount++;  
  42.         threshold = (int) (newCapacity * loadFactor);  
  43.         table = newMap;  
  44.                 //和HashMap算法是一样的,建议看HashMap里面的写法好理解点。  
  45.         for (int i = oldCapacity; i-- > 0;) {  
  46.             for (Entry<K, V> old = oldMap[i]; old != null;) {  
  47.                 Entry<K, V> e = old;  
  48.                 old = old.next;  
  49.   
  50.                 int index = (e.hash & 0x7FFFFFFF) % newCapacity;  
  51.                 e.next = newMap[index];  
  52.                 newMap[index] = e;  
  53.             }  
  54.         }  
  55.     }  

 

 

七.总结

 

  HashMap Hashtable
出现时间 JDK1.2,所以代码质量更高,更容易明白 JDK1.0
并发控制 没有考虑并发 所有方法都加了synchronized,即使有些我认为不需要的也加了
是否接受值为null的Key 或Value 接受 不接收。put等方法里面:if (value == null) {
            显示throw new NullPointerException();
        };int hash=key.hashcode隐示throw NullPointerException();
初始化table 缺省容量16。初始化时可以指定initial capacity,若不是2的次方,HashMap将选取第一个大于initial capacity 的2的次方值作为其初始长度 缺省容量11。初始化时可以指定initial capacity
扩容 添加Entry后判断是否该扩容。扩容至2*oldCapacity 先判断是否扩容再添加Entry。扩容至2*oldCapacity + 1
数据遍历的方式 Iterator Iterator 和 Enumeration
是否支持fast-fail 支持fast-fail
用Iterator遍历,支持fast-fail
用Enumeration不支持fast-fail.
hash算法和index算法 优于Hashtable,通过对Key的hash做移位运算和位的与运算,使其能更广泛地分散到数组的不同位置 当数组长度较小,并且Key的hash值低位数值分散不均匀时,不同的hash值计算得到相同下标值的几率较高
实现和继承 extends AbstractMap 骨架结构的体现,代码质量上去了 extends Dictionary implements Map 直接实现Map接口。多基础了一个已过时的经Dictionary类,就不用去管了
     

 

分享到:
评论

相关推荐

    02-Java集合容器面试题(2020最新版)-重点.pdf

    ### Java集合容器知识点详解 #### 一、集合容器概述 - **定义**:集合容器是Java平台提供的标准组件,主要用于存储对象。...通过本篇文章的学习,希望读者能够更好地理解和应用Java集合容器,提升编程技能。

    java_词汇表速查手册

    - `Hashtable`:键值对存储。 - `Vector`:可变大小的数组。 #### Collection interface(容器类接口) - **定义**:定义容器类共同的操作。 - **目的**: - 提供一致性的编程模型。 - 支持不同的容器实现。 #...

    unity3d脚本.pdf

    - **Hashtable**:表示哈希表。 - **Input**:表示输入。 - **JointDrive**:表示关节驱动。 - **JointLimits**:表示关节限制。 - **JointMotor**:表示关节马达。 - **JointSpring**:表示关节弹簧。 - **Keyframe...

    hashMap和hashTable的区别

    ### hashMap和hashTable的区别 #### 一、简介与基本概念 `HashMap` 和 `HashTable` 都是 Java 集合框架中非常重要的数据结构,它们都实现了 `Map` 接口,用于存储键值对。尽管它们在功能上有很多相似之处,但在...

    阿里校招社招常考面试题(86题 11页).pdf

    #### 二、Vector, ArrayList, LinkedList 区别 1. **存储结构**: - **Vector** 和 **ArrayList**:采用数组实现,方便随机访问。 - **LinkedList**:采用链表实现,适合频繁的插入和删除操作。 2. **线程安全**...

    java软件技术文档-深入java8的集合5:Hashtable的实现原理.pdf

    **二、Hashtable属性** Hashtable的主要属性包括: 1. `table`:这是一个内部类`Entry`的数组,存储键值对。 2. `count`:记录哈希表中键值对的数量。 3. `threshold`:扩容的阈值,等于容量乘以负载因子。 4. `...

    2021-2022计算机二级等级考试试题及答案No.18262.docx

    Hashtable hashtable = new Hashtable(); hashtable.put("x", "12345"); hashtable.put("y", "67890"); hashtable.put("a", "abcde"); System.out.println(hashtable.get("a")); ``` 这段代码中,`Hashtable`中存储...

    java面试知识

    - **IOC容器**:管理对象生命周期和依赖关系。 - **AOP**:面向切面编程,分离关注点。 - **模块化**:提供多种模块,如Web、Data Access等。 ##### 事务概述 - **ACID特性**:原子性、一致性、隔离性、持久性。 -...

    华中科技大学JAVA考前复习资料

    - **描述**:`Hashtable` 是 Java 中最早的键值对映射容器之一。 - **应用场景**:适用于需要快速查找数据的情况,例如作为查找表。 - **特点**:线程安全、不允许 null 键和 null 值。 3. **Character 流与 ...

    2024年java面试题-java集合相关面试题

    ### 二、常用的集合类 #### 1. Map接口和Collection接口 - **Map接口**:表示键值对映射关系的集合。 - **Collection接口**:表示单个对象的集合。 #### 2. Collection接口的子接口 - **Set接口**:不允许包含...

    java-all.pdf

    #### 二、Java语言基础 ##### 1. 数据类型与变量 Java 支持多种数据类型,包括基本数据类型(如 `int`, `double`, `char` 等)和引用数据类型(如类、数组等)。 - **基本数据类型**:例如 `int` 用于整数,`...

    Hashtable和HashMap的区别:

    ### Hashtable与HashMap的区别详解 #### 一、基本概念与历史背景 在Java编程语言中,`Hashtable` 和 `HashMap` 都是用来存储键值对的数据结构。这两种数据结构虽然相似,但是在实现细节上存在显著差异。 1. **...

    Java 基础 常识

    #### 二、基本数据类型与String **1. String是否为基本数据类型?** - **结论**:不是。 - **解释**:Java中的基本数据类型包括`byte`、`short`、`int`、`long`、`float`、`double`、`char`、`boolean`。 - **...

    struts2标签大全

    - `s:hashtable`:遍历Hashtable对象。 - `s:if`和`s:else`:条件判断,可以根据条件显示内容。 6. **Include标签** - `s:include`:包含其他JSP或Freemarker模板。 7. **Message标签** - `s:messages`:显示...

    java面试总结

    - **JavaEE**: 企业版,除了标准版的功能外,还包含了Web容器、EJB容器等企业级功能。 - **JavaME**: 微小版,主要用于嵌入式设备和移动设备。 #### 三十九、JDK、JRE、JVM的区别 - **JDK**: Java Development Kit...

    linux 虚拟文件系统数据结构关系

    - **dentry_hashtable**: `dentry`的哈希表,用于快速查找文件名到`inode`的映射。 - **super_blocks**: `super_block`的哈希表,用于快速查找文件系统。 #### 总结 这些数据结构共同构成了Linux VFS的核心框架,...

    HashMap与HashTable区别

    ### HashMap与HashTable的区别 在Java编程语言中,`HashMap`和`HashTable`是两种非常重要的数据结构,它们都实现了`Map`接口,并提供了键值对的存储方式。这两种数据结构虽然相似,但在实现细节和使用场景上存在...

    黑马Java基础口述总结

    - **定义**:用于存储数据的容器。 - **定义格式**:数据类型 变量名 = 初始值; - **注意事项**: - 在使用变量前必须先声明。 - 数据类型与变量存储的数据类型一致。 - 同一作用域内不能重复声明相同变量。 ###...

    Java岗面试题大全.pdf

    - **字节流**:处理字节数据,通常用于二进制文件的读写。 - **字符流**:处理字符数据,通常用于文本文件的读写。 #### 5. 阻塞 I/O 模型 - **特点**:每次I/O操作必须等待完成才能继续执行后续操作。 #### 6. 非...

Global site tag (gtag.js) - Google Analytics