Java HashMap 和 Hashtable 有什么区别?
HashMap
和 Hashtable
都是Java集合框架中用于存储键值对的类,但它们之间有一些关键的区别。
1. 线程安全性:
-
HashMap:
HashMap
是非线程安全的,不同线程可以同时修改HashMap
实例,可能导致不一致的结果。 -
Hashtable:
Hashtable
是线程安全的,它的方法都是同步的,多个线程不能同时修改一个Hashtable
实例,从而避免了竞态条件。
示例代码:
// HashMap 非线程安全示例
Map<String, Integer> hashMap = new HashMap<>();
Runnable runnable = () -> {
for (int i = 0; i < 1000; i++) {
hashMap.put("Key" + i, i);
}
};
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
2. null 键和值:
-
HashMap: 允许键和值为
null
。 -
Hashtable: 不允许键和值为
null
,否则会抛出NullPointerException
。
示例代码:
// HashMap 允许 null 键和值
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put(null, 1);
hashMap.put("Key", null);
// Hashtable 不允许 null 键和值
Hashtable<String, Integer> hashtable = new Hashtable<>();
// 下面的语句会抛出 NullPointerException
hashtable.put(null, 1);
hashtable.put("Key", null);
3. 性能:
-
HashMap: 相对于
Hashtable
,HashMap
的性能更好,因为它不是线程安全的。 -
Hashtable: 由于需要确保线程安全性,
Hashtable
的性能通常较差。
示例代码:
// 测试 HashMap 性能
Map<String, Integer> hashMap = new HashMap<>();
long startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
hashMap.put("Key" + i, i);
}
long endTime = System.nanoTime();
System.out.println("HashMap Time: " + (endTime - startTime) / 1000000 + "ms");
// 测试 Hashtable 性能
Hashtable<String, Integer> hashtable = new Hashtable<>();
startTime = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
hashtable.put("Key" + i, i);
}
endTime = System.nanoTime();
System.out.println("Hashtable Time: " + (endTime - startTime) / 1000000 + "ms");
总的来说,如果不需要线程安全性,并且需要更好的性能,通常推荐使用 HashMap
。如果需要线程安全性,则可以使用 Hashtable
或 ConcurrentHashMap
(ConcurrentHashMap
是 Java 5 引入的,提供了更好的性能)。在新代码中,更常使用 HashMap
或 ConcurrentHashMap
。