HashMap 底 层 实 现 原 理 /HashMap 与
HashTable 区别/HashMap 与 HashSet 区别
①HashMap 的工作原理
HashMap 基于 hashing 原理,我们通过 put()和 get()方法储存和获取对象。当我
们将键值对传递给 put()方法时,它调用键对象的 hashCode()方法来计算
hashcode,让后找到 bucket 位置来储存值对象。当获取对象时,通过键对象的
equals()方法找到正确的键值对,然后返回值对象。HashMap 使用链表来解决碰
撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap 在每
个链表节点中储存键值对对象。
当两个不同的键对象的 hashcode 相同时会发生什么? 它们会储存在同一个
bucket 位置的链表中。键对象的 equals()方法用来找到键值对。
因为 HashMap 的好处非常多,我曾经在电子商务的应用中使用 HashMap 作为缓
存。因为金融领域非常多的运用 Java,也出于性能的考虑,我们会经常用到
HashMap 和 ConcurrentHashMap。
②HashMap 和 Hashtable 的区别
HashMap 和 Hashtable 都实现了 Map 接口,但决定用哪一个之前先要弄清楚它们
之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。
1. HashMap 几乎可以等价于 Hashtable,除了 HashMap 是非 synchronized 的,并可以
接受 null(HashMap 可以接受为 null 的键值(key)和值(value),而 Hashtable 则不行)。
2. HashMap 是非 synchronized,而 Hashtable 是 synchronized,这意味着 Hashtable 是线
程安全的,多个线程可以共享一个 Hashtable;而如果没有正确的同步的话,多个线
程是不能共享 HashMap 的。Java 5 提供了 ConcurrentHashMap,它是 HashTable 的替
代,比 HashTable 的扩展性更好。
3. 另 一 个 区 别 是 HashMap 的 迭 代 器 (Iterator) 是 fail-fast 迭 代 器 , 而 Hashtable 的
enumerator 迭代器不是 fail-fast 的。所以当有其它线程改变了 HashMap 的结构(增
加或者移除元素),将会抛出 ConcurrentModificationException,但迭代器本身的
remove()方法移除元素则不会抛出 ConcurrentModificationException 异常。但这并不
是一个一定发生的行为,要看 JVM。这条同样也是 Enumeration 和 Iterator 的区别。
4. 由于 Hashtable 是线程安全的也是 synchronized,所以在单线程环境下它比 HashMap
要慢。如果你不需要同步,只需要单一线程,那么使用 HashMap 性能要好过
Hashtable。
5. HashMap 不能保证随着时间的推移 Map 中的元素次序是不变的。