这两个类是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;
}
2.HashMap的put方法及其使用的相关方法实现代码,以下做了注释:
/**
* 使用位移算法对哈希码给予补充,防止出现大量的0、1重复,这样得到的index重复的几率就很大,经过补充位移运算后,
* 可以使哈希码的0、1分布更加均匀,再经过indexFor()方法计算得到的index重复的几率就小很多,这就是HashMap散列
* 算法相比于Hashtable的哈希算法更优化的关键所在。
* 需要注意的是key=null时,index=0。
*/
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
/**
* 通过哈希值和table的最大存储位置的位与运算,得到一个小于length的值作为index。
*/
static int indexFor(int h, int length) {
return h & (length-1);
}
/**
* HashMap的put方法
*/
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
//得到哈希值,hashCode()方法为native方法,估计是C、C++或者汇编实现的
int hash = hash(key.hashCode());
//得到index
int i = indexFor(hash, table.length);
/* 得到index,遍历table[index]寻找key相同的对象,如果不存在增加一个Entry对象 */
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
/* 注意这里不仅要比较哈希值还要比较key对象,找到后覆盖原来的值 */
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
/* 如果根据哈希值没找到对应的entry对象,在entry链表末尾加入新的entr对象 */
modCount++;
addEntry(hash, key, value, i);
return null;
}
3.下面比较一下两个类到底有什么异同。
相同点:
(1)这两个类存储key-value对象的数据结构基本相同,都是将
key-value封装在entry对象中,entry中有指向下一个entry对象的引用(Entry next),这样就可以形成一个链表,而在类的主体中保存了一个Entry链表的数组(Entry[] table)来存储Entry对象,具体存储结构如下图:
(2)取数据的方法基本相同,在哈希算法的概念里面,每一个链表应该称之为一个"桶",每个桶都有一个编号
(也就是index),通过编号我们可以很快的从桶里面取出东西,但是如果桶里面装的东西多了,那就要一个一个的找,会比较慢,所以我们要让东西放的均匀一些,让我们每次取东西都不至于太慢。因此,取东西效率取决于我们当初如何存东西,在这一点上两个类的思想是一样的。
不同点;
通过比较两个类put方法的实现,我们会发现它们之间的区别:
(1)Hashtable的put方法有synchronized修饰,说明该put方法实现了同步,达到了一定的线程安全级别,
而HashMap的put方式没有实现同步,是非线程安全类,当然,单线程情况下,HashMap无疑拥有更好的执行效率而不用去考虑线程安全问题。
(2)通过key获取index的过程有很大差别,其实这是两个类最重要的区别,在代码的注释里面已经给出了分析,HashMap的实现方式无疑使一种更优的实现,所以我们在单线程的环境下,或者在某些安全的多线程环境下都应该优先使用HashMap。当然,并发环境下,我们还可以考虑使用NIO包里面的类,这个问题将在其他的文章里讨论。
- 大小: 11 KB
分享到:
相关推荐
综上所述,`HashMap`和`HashTable`在多个方面存在差异。选择哪一个取决于特定的应用场景和需求: - 如果需要线程安全并且能够接受一定的性能损耗,可以选择`HashTable`。 - 如果追求更高的性能且可以自己处理线程...
### hashMap和hashTable的区别 #### 一、简介与基本概念 `HashMap` 和 `HashTable` 都是 Java 集合框架中非常重要的数据结构,它们都实现了 `Map` 接口,用于存储键值对。尽管它们在功能上有很多相似之处,但在...
HashTable和HashMap类似,也是基于哈希表实现的。但是,HashTable是线程安全的,而HashMap不是。HashTable使用synchronized关键字来实现线程安全。 HashMap和HashTable的区别 1. 线程安全:HashMap不是线程安全的...
Java集合专题总结:HashMap和HashTable源码...本文总结了HashMap和HashTable的源码学习和面试总结,涵盖了它们的存储结构、构造方法、get和put方法的源码分析、Hash表的特点和缺点、HashTable和HashMap的区别等内容。
### HashMap与HashTable和HashSet的区别 #### 一、概述 在Java集合框架中,`HashMap`, `HashTable` 和 `HashSet` 是三个重要的数据结构,它们分别实现了`Map`接口和`Set`接口,提供了不同的功能来满足不同的编程...
在Java编程语言中,`HashMap`和`HashTable`是两种非常重要的数据结构,它们都实现了`Map`接口,并提供了键值对的存储方式。这两种数据结构虽然相似,但在实现细节和使用场景上存在显著差异。下面将详细介绍`HashMap`...
在Java编程语言中,`HashMap`和`Hashtable`是两种非常重要的数据结构,它们都用于存储键值对。然而,在实际应用过程中,这两种数据结构有着本质的不同,下面将详细介绍这些差异。 #### 1. 历史背景及实现原理 - **...
hashmap和hashtable的区别
在Java编程语言中,`HashMap`和`HashTable`都是实现键值对存储的数据结构,但它们之间存在一些显著的区别,这些区别主要体现在线程安全性、性能、null值处理以及一些方法特性上。以下是对这两个类的详细分析: 1. ...
hashMap和Hashtable的区别1
HashMap 和 Hashtable 是 Java 集合框架中两个重要的映射数据结构,它们都实现了 Map 接口,但具有显著的差异。以下将详细介绍这两个类的主要区别: 1. 线程安全性: - HashMap 不是线程安全的,这意味着在多线程...
11.HashMap和HashTable的区别.avi
HashMap和Hashtable的区别Java开发Java经验技巧共2页.pdf.zip
- HashMap 和 Hashtable 都实现了 Map 接口,HashMap 更快但不是线程安全的,而 Hashtable 是线程安全但较慢。WeakHashMap 则使用弱引用作为键,有助于防止内存泄漏。 - 在选择使用哪种数据结构时,需要考虑性能需求...
其中,HashMap, HashTable, LinkedHashMap, TreeMap 是四种常用的 Map 实现类,每种类都有其特点和用途。本文将对这四种 Map 实现类进行比较和分析。 HashMap HashMap 是 Java 中最常用的 Map 实现类,它根据键的 ...
2. 键和值的 null 值:HashMap 的键和值都允许有 null 值存在,而 HashTable 则不行。 3. 效率:HashMap 的效率比 HashTable 的要高。 HashMap 的内部结构 HashMap 的内部结构是哈希表,具有较快的查询速度和相对...
在Java编程语言中,集合框架是处理对象数组的重要工具,其中`List`、`ArrayList`、`Vector`、`HashTable`和`HashMap`是五个关键的接口和类,它们各有不同的特性和用途。以下是这些概念的详细解释: 1. **List接口**...
Java面试题11.HashMap和HashTable的区别.mp4
HashMap和HashTable的区别?但是如果想线程安全有想效率高?
在Java编程语言中,`HashMap`和`HashTable`都是实现`Map`接口的数据结构,用于存储键值对。它们在很多方面有所不同,这些差异主要体现在线程安全性、迭代器类型、null值支持以及哈希码处理等方面。以下是关于两者...