Differences Between HashMap and Hashtable in Java – Java中HashMap和Hashtable的区别

最后修改: 2018年 12月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we are going to focus on the core differences between the Hashtable and the HashMap.

在这个简短的教程中,我们将重点讨论HashtableHashMap之间的核心差异。

2. Hashtable and HashMap in Java

2.Java中的HashtableHashMap

Hashtable and HashMap are quite similar – both are collections that implement the Map interface.

HashtableHashMap非常相似–都是实现Map接口的集合。

Also, the put(), get(), remove(), and containsKey() methods provide constant-time performance O(1). Internally, these methods work based on a general concept of hashing using buckets for storing data.

另外,put()get()remove()containsKey()方法提供了恒定时间性能O(1)。在内部,这些方法是基于使用桶来存储数据的散列的一般概念工作的。

Neither class maintains the insertion order of the elements. In other words, the first item added may not be the first item when we iterate over the values.

这两个类都没有维护元素的插入顺序。换句话说,当我们对数值进行迭代时,第一个添加的项目可能不是第一个项目。

But they also have some differences that make one better than another in some situations. Let’s look closer at these differences.

但它们也有一些区别,在某些情况下使一个比另一个更好。让我们仔细看看这些差异。

3. Differences Between Hashtable and HashMap

3.HashtableHashMap之间的区别

3.1. Synchronization

3.1.同步化

Firstly, Hashtable is thread-safe and can be shared between multiple threads in the application.

首先,Hashtable是线程安全的,可以在应用程序的多个线程之间共享。

On the other hand, HashMap is not synchronized and can’t be accessed by multiple threads without additional synchronization code. We can use Collections.synchronizedMap() to make a thread-safe version of a HashMap. We can also just create custom lock code or make the code thread-safe by using the synchronized keyword.

另一方面,HashMap是不同步的,如果没有额外的同步代码,就不能被多个线程访问。我们可以使用Collections.synchronizedMap() 来制作一个线程安全的HashMap版本。我们也可以直接创建自定义锁代码,或者通过使用synchronized关键字使代码成为线程安全的。

HashMap is not synchronized, therefore it’s faster and uses less memory than Hashtable. Generally, unsynchronized objects are faster than synchronized ones in a single threaded application.

HashMap是不同步的,因此它比Hashtable更快,使用的内存更少。一般来说,在单线程应用程序中,不同步的对象比同步的对象要快。

3.2. Null Values

3.2.空值

Another difference is null handling. HashMap allows adding one Entry with null as key as well as many entries with null as value. In contrast, Hashtable doesn’t allow null at all. Let’s see an example of null and HashMap:

另一个区别是对null的处理。HashMap允许添加一个带有null键的Entry,以及许多带有null值的条目。相反,Hashtable完全不允许null。让我们看看nullHashMap的一个例子。

HashMap<String, String> map = new HashMap<String, String>();
map.put(null, "value");
map.put("key1", null);
map.put("key2", null);

This will result in:

这将导致。

assertEquals(3, map.size());

Next, let’s see how Hashtable is different:

接下来,让我们看看Hashtable有什么不同。

Hashtable<String, String> table = new Hashtable<String, String>();
table.put("key", null);

This results in a NullPointerException. Adding an object with null as a key also results in a NullPointerException:

这导致了一个NullPointerException。添加一个以null为键的对象也会导致NullPointerException

table.put(null, "value");

3.3. Iteration Over Elements

3.3.元素上的迭代

HashMap uses Iterator to iterate over values, whereas Hashtable has Enumerator for the same. The Iterator is a successor of Enumerator that eliminates its few drawbacks. For example, Iterator has a remove() method to remove elements from underlying collections.

HashMap使用Iterator 来迭代数值,而HashtableEnumerator来迭代。IteratorEnumerator的继承者,消除了它的一些缺点。例如,Iterator有一个remove()方法来从底层集合中移除元素。

The Iterator is a fail-fast iterator. In other words, it throws a ConcurrentModificationException when the underlying collection is modified while iterating. Let’s see the example of fail-fast:

Iterator是一个fail-fast迭代器。换句话说,当迭代过程中底层集合被修改时,它会抛出一个ConcurrentModificationException 。让我们来看看fail-fast的例子。

HashMap<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");

Iterator<String> iterator = map.keySet().iterator();
while(iterator.hasNext()){ 
    iterator.next();
    map.put("key4", "value4");
}

This throws a ConcurrentModificationException exception because we are calling put() while iterating over the collection.

这会抛出一个ConcurrentModificationException异常,因为我们在迭代集合的同时调用put()

4. When to Choose HashMap Over Hashtable

4.何时选择HashMap而不是Hashtable

We should use HashMap for an unsynchronized or single threaded application.

对于非同步或单线程的应用程序,我们应该使用HashMap

It is worth mentioning that since JDK 1.8, Hashtable has been deprecated. However, ConcurrentHashMap is a great Hashtable replacement. We should consider ConcurrentHashMap to use in applications with multiple threads.

值得一提的是,从JDK 1.8开始,Hashtable已经被弃用。然而,ConcurrentHashMap是一个很好的Hashtable替代品。我们应该考虑将ConcurrentHashMap用于具有多线程的应用程序中。

5. Conclusion

5.结论

In this article, we illustrated differences between HashMap and Hashtable and what to keep in mind when we need to choose one.

在这篇文章中,我们说明了HashMapHashtable之间的区别,以及当我们需要选择一个时需要注意的事项。

As usual, the implementation of all these examples and code snippets are over on Github.

像往常一样,所有这些例子和代码片段的实现都在Github上