这两个类是java中进行key-value存储、查询的常用类,如果我们学习过哈希算法就会知道key-value查询的效率依赖于如何存储,换句话说,如果存的好,拿出来就容易,存的不好,拿出来就不方便。两个类有很多相似之处,他们之间的关系和区别到底如何,先看看它们两个当中最核心方法put的实现。
1.Hashtable的put方法的实现,以下代码做了注释:
- /**
- * Hashtable的put方法,是同步的,可以在多线程环境下确保原子性执行,index值的计算过程非常简单,
- * 但是运气不好的话有可能得到大量重复的index,大量的key-value存储在相同的Entry链表中,从而降
- * 低了get操作的执行效率
- */
- 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 = key.hashCode();
- /* 通过哈希值获取index */
- int index = (hash & 0x7FFFFFFF) % tab.length;
- /* 遍历Entry链表 */
- for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
- /* 注意这里不仅要比较哈希值还要比较key对象 */
- if ((e.hash == hash) && e.key.equals(key)) {
- V old = e.value;
- e.value = value;
- return old;
- }
- }
- modCount++;
- /* 如果装不下了,就扩充容量,重新获取index */
- if (count >= threshold) {
- // Rehash the table if the threshold is exceeded
- rehash();
- tab = table;
- index = (hash & 0x7FFFFFFF) % tab.length;
- }
- /* 如果根据哈希值没找到对应的entry对象,在entry链表末尾加入新的entr对象 */
- Entry<K,V> e = tab[index];
- tab[index] = new Entry<K,V>(hash, key, value, e);
- count++;
- return null;
- }