Java数据结构源码分析-HashTable
2016-06-05 15:05
495 查看
1.HashTable
HashTable同HashMap在数据结构的层面上是一致的,同时通过数组+链表的形式来存储数据。其方法的功能和实现方式也基本一致。
就不在此处赘述,如果要详细了解可以参看HashMap的源码分析:
http://blog.csdn.net/cweeyii/article/details/51583154
下面我们给出下几个重要方法的对比:
//HashMap的Put方法 public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } //HashTable的Put方法 public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = hash(key); 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; return old; } } modCount++; if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; hash = hash(key); index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. Entry<K,V> e = tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; return null; } //HashMap的构造方法 public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; threshold = initialCapacity; init(); } //HashTable的构造方法: public Hashtable(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal Load: "+loadFactor); if (initialCapacity==0) initialCapacity = 1; this.loadFactor = loadFactor; table = new Entry[initialCapacity]; threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); initHashSeedAsNeeded(initialCapacity); }
2.HashMap和HashTable异同
HashMap构造时,并不分配table数组的内存空间,其实在第一次调用put方法时分配,并且其分配的空间是2的幂次大小,默认为16。 而HashTable在构造时分配table数据的内存空间,默认大小为11在继承层次上,HashMap是Map接口的一个实现,而HashTable是Dictionary的一个子类。其使用上这个并不存在太大区别
HashMap的所有方法是非同步的方法,因此在不考虑线程间的共享的情况下,其速度更快。而HashTable里所有方法都是基于对象级别同步的,因此其是线程安全的。对于线程安全的结构HashMap提供了一个ConcurrentHashMap的选择,其实现原理比HashTable更加优异,这也是导致HashTable已经几乎不被人使用的原因。
HashMap可以将空值作为一个表的条目的key或者value,HashMap中由于键不能重复,因此只有一条记录的Key可以是空值,而value可以有多个为空,但HashTable不允许null值(键与值均不行)
内存扩容时采取的方式也不同,Hashtable采用的是2*old+1,而HashMap是2*old
哈希值的计算方法不同,Hashtable直接使用的是对象的hashCode,而HashMap则是在对象的hashCode的基础上还进行了一些变化
3.总结
1.由于HashMap系列具有:非线程安全的HashMap和线程安全的ConcurrentHashMap,因此可以完全忘记HashTable类的存在2.HashTable和HashMap的区别一直是各种面试时考察的内容:主要记住第二下节异同中的: 3、4就行了,其他可以了解
相关文章推荐
- Java数据结构源码分析-HashSet
- 数据结构之链表
- 数据结构之链表
- 数据结构之链表
- 【数据结构】二叉搜索树
- 【数据结构与算法】深入浅出递归和迭代的通用转换思想
- 【数据结构与算法】深入浅出递归和迭代的通用转换思想
- 算分与数据结构 - 冒泡思想
- 数据结构二叉树——建立二叉树、中序递归遍历、非递归遍历、层次遍历
- C/C++,数据结构实现两个链表的合并(尾插法建立单链表,求链表长度,直接插入排序)
- C/C++,数据结构单链表(采用C++&quot;引用&quot;方法)(寻找节点、在某处插入结点、删除某位置结点)
- C/C++,数据结构单链表实现约瑟夫环
- 笔试,面试,C/C++,数据结构单链表排序(改进冒泡排序)
- 数据结构学习之单向链表[附Java实现代码]
- 数据结构二叉树的递归遍历
- hjr-数据结构
- 详解五大排序算法
- 数据结构_9:位算法
- 经典算法之堆排序算法
- 算法与数据结构 - 贪心算法