java面试题-HashMap和Hashtable 区别是什么
Java中的HashMap和Hashtable都是常用的键值对集合类,但它们之间存在许多差异。在本教程中,我们将深入研究HashMap和Hashtable的特性、用法,并提供详细的代码示例,以帮助初学者更好地理解它们。
1. 线程安全性
HashMap
HashMap是非线程安全的,这意味着在多线程环境中使用时需要额外的同步措施。下面是一个简单的HashMap示例:
Map<String, String> hashMap = new HashMap<>();
hashMap.put("key1", "value1");
hashMap.put("key2", "value2");
// 其他线程可能导致并发问题,需要额外的同步措施
Hashtable
Hashtable是线程安全的,但这也导致了性能上的一些损失。它的方法都是Synchronized的,下面是一个Hashtable示例:
Hashtable<String, String> hashtable = new Hashtable<>();
hashtable.put("key1", "value1");
hashtable.put("key2", "value2");
// 线程安全,但性能较差
2. 处理null值
HashMap
HashMap允许key和value都为null。下面是一个允许null值的HashMap示例:
Map<String, String> hashMap = new HashMap<>();
hashMap.put(null, "value1");
hashMap.put("key2", null);
Hashtable
Hashtable不允许key和value为null。任何试图存储null键或值的操作都会引发NullPointerException。
3. 迭代器
HashMap
HashMap的迭代器是fail-fast的,即在迭代过程中,如果其他线程对HashMap进行了结构上的修改,会抛出ConcurrentModificationException异常。下面是一个HashMap迭代器示例:
Map<String, String> hashMap = new HashMap<>();
hashMap.put("key1", "value1");
hashMap.put("key2", "value2");
Iterator<Map.Entry<String, String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
// 在迭代过程中其他线程修改HashMap结构会抛出异常
System.out.println(entry.getKey() + ": " + entry.getValue());
}
Hashtable
Hashtable使用了enumerator迭代器,但它不推荐使用,因为它在遇到并发修改时不会抛出异常,而是默默地接受新的修改。
4. hash的计算方式
HashMap
HashMap计算hash值,使用key的hashCode方法来计算hash。下面是一个计算hash值的HashMap示例:
class MyKey {
@Override
public int hashCode() {
// 自定义hashCode计算逻辑
return Objects.hash(/*...*/);
}
}
Map<MyKey, String> hashMap = new HashMap<>();
hashMap.put(new MyKey(), "value1");
Hashtable
Hashtable也使用key的hashCode方法来计算hash值。
5. 默认初始大小和扩容方式
HashMap
HashMap的默认初始大小是16,而且容量必须是2的整数次幂。在扩容时,将容量变为原来的2倍。
Hashtable
Hashtable的默认初始大小是11,而且在扩容时将容量变为原来的2倍加1。
6. contains方法
HashMap
HashMap没有contains方法。如果想检查某个值是否存在,可以使用containsValue方法。
Hashtable
Hashtable包含contains方法,类似于containsValue,用于检查特定的值是否存在。
7. 父类
HashMap
HashMap继承自AbstractMap类。
Hashtable
Hashtable继承自Dictionary类,这在Java中已经被淘汰,推荐使用Map的实现类。
综上所述,推荐在单线程环境下使用HashMap替代Hashtable。如果需要多线程使用,推荐使用ConcurrentHashMap,因为它既提供了线程安全性,又在性能上进行了优化。
关键词: HashMap, Hashtable, Java集合, 线程安全, null处理, 迭代器, hash计算, 初始大小, 扩容方式
摘要: 本教程详细解析了HashMap和Hashtable之间的差异,包括线程安全性、处理null值、迭代器、hash计算方式等。通过示例代码,帮助初学者更好地理解并正确使用这两个集合类。
备注: 关注站长获取更多详情。
- 本文标签: Java 面试题
- 本文链接: https://www.jietongc.com/article/112
- 版权声明: 本文由大熊科技原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权