简谈JAVA基础--HashTable
来源:互联网 发布:oracle恢复原来的数据 编辑:程序博客网 时间:2024/06/16 02:03
HashTable与HashMap的区别:
HashTable底层数据结构与HashMap相差不多,可以看一下简谈JAVA基础--HashMap
HashTable由于每个方法都通过synchronized关键字来进行修饰,所以说是线程安全的。
而HashMap当多个线程同时操作时,没有同步机制所以会导致数据的不安全。
HashTable键值都不可以为Null。而HashMap的key可以为null。
如果在程序中对HashTable进行类似put( null , null )这样的操作时;编译器是可以通过的,但是会在实际运行时抛出异常。
HashMap的长度为2的幂次方,而HashTable为2的幂次方+1。
所以在扩容操作时,HashMap扩展为原先二倍,HashTable为二倍+1。
基本参数:
Entry<?,?>[] table -- 存放Entry数组(实际上每个Entry就是一个键值对,当Hash值相同时,以链表形式保存)
count -- 相当于size长度,代表当前已存在键值对个数
threshold -- 容量:可最大存储键值对个数
loadFactor -- 加载因子
initialCapacity -- 实例化长度。
实例化源码:
public Hashtable(int initialCapacity, float loadFactor) { // 初始化长度不能小于0 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); // 加载因子不能小于等于0,loadFactor不能为非数字 if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal Load: "+loadFactor); // 如果初始化长度为0,设置为1 if (initialCapacity==0) initialCapacity = 1; // 加载因子赋值 this.loadFactor = loadFactor; // 创建长度为initialCapacity的Entry数组 table = new Entry<?,?>[initialCapacity]; // 容量为最大数 与 初始长度 * 加载因子中较小的一个 threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);}
Put操作源码:
public synchronized V put(K key, V value) { // Make sure the value is not null // value不能为空 if (value == null) { throw new NullPointerException(); } // 将当前table赋给tab[] // Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table; // 得到key的hash int hash = key.hashCode(); // 获得数组中的索引 int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") // 将tab数组中该索引地址内容赋给 entry Entry<K,V> entry = (Entry<K,V>)tab[index]; // 如果有相同key的存在,覆盖value, return for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } // 没有key值存在则添加键值 addEntry(hash, key, value, index); return null;}
addEntry源码:
private void addEntry(int hash, K key, V value, int index) { modCount++; // 原对象table赋给tab[] Entry<?,?> tab[] = table; // 如果当前键值对个数大于等于 最大可容纳数量 if (count >= threshold) { // Rehash the table if the threshold is exceeded // 进行扩容操作 rehash(); // 扩容后的table赋给tab tab = table; // 获取数组索引 hash = key.hashCode(); index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. // 创建一个Enrty赋给数组索引位置 @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>) tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++;}
rehash(扩容)源码:
protected void rehash() { // 原数组长度 int oldCapacity = table.length; // 原数组 Entry<?,?>[] oldMap = table; // overflow-conscious code // 新数组长度为原数组长度 * 2 + 1 int newCapacity = (oldCapacity << 1) + 1; // 如果新长度超过最大值,新长度为最大值 if (newCapacity - MAX_ARRAY_SIZE > 0) { if (oldCapacity == MAX_ARRAY_SIZE) // Keep running with MAX_ARRAY_SIZE buckets return; newCapacity = MAX_ARRAY_SIZE; } // 定义新数组 Entry<?,?>[] newMap = new Entry<?,?>[newCapacity]; // 操作统计+1 modCount++; // 新数组可容纳键值对数量 threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1); // 修改当前table引用为新数组 table = newMap; // 将原数组中的元素。转移到新数组当中 for (int i = oldCapacity ; i-- > 0 ;) { for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) { Entry<K,V> e = old; old = old.next; int index = (e.hash & 0x7FFFFFFF) % newCapacity; e.next = (Entry<K,V>)newMap[index]; newMap[index] = e; } }}
阅读全文
0 0
- 简谈JAVA基础--HashTable
- Java基础-了解Hashtable
- java基础_hashmap,hashtable,hashset
- java基础---HashMap与HashTable
- java基础---HashMap与HashTable
- java基础:HashMap Hashtable LinkedHashMap TreeMap
- java基础 数据集合 hashmap hashtable
- 【Java基础提高】HashTable源码分析(六)
- java基础--hashTable与concurrentHashMap的比较
- Java基础——HashTable源码分析
- hashtable基础
- java hashtable
- java Hashtable
- java-hashTable
- java HashTable
- Java- HashTable
- 【java】HashTable
- java基础—Hashtable,HashMap,TreeMap的区别
- 资讯精选 | 物联网时代_选择一个技术_就是选择了一种生态
- 用gridview模仿日历并实现签到功能
- vue.js移动端app实战4:上拉加载以及下拉刷新
- Java语言基础小结3
- Android组件化初探
- 简谈JAVA基础--HashTable
- Ruby元编程-学习笔记(一)-对象模型
- caffe训练自己的数据集——1. 数据准备
- Android基础总结八:单选框RadioGroup,RadioButton的使用
- Android 模拟器下载、编译及调试
- git的使用与常用linux命令
- Swift
- PHP后台之调试手段(新手必备)
- Ruby元编程-学习笔记(三)-代码块