一:HashTable与HashMap之间的区别
HashTable | HashMap | |
内部存储元素 | 无序 | |
底层实现 | 数组+链表 | 数组+链表 |
实现原理 | ||
效率 | 低 | 高 |
null | 不接受null key、null value | 可接受null key、null value |
线程同步 | 同步[synchronized实现] | 不同步 |
线程安全 | synchronized[线程安全] | 非synchronized[线程不安全] |
扩容方式 | old * 2 + 1 | old * 2 |
默认容量 | 11 | 16 |
父类 | Dictionary | AbstractMap |
方法 | contains() | containsKey()、contaionsValue() |
延伸:
HashMap的底层实现:
有文章提到:HashMap的实现原理为:基于拉链法的散列表,也有文章说是:散列表。到底是什么呢?
哈希表[hash table]也叫散列表,哈希表的主干就是数组。
数据结构的物理存储结构只有两种:顺序存储结构和链式存储结构(像栈,队列,树,图等是从逻辑结构去抽象的,映射到内存中,也这两种物理组织形式)。
HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。
相同点:
同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口
HashMap同步的方式
Map m = Collections.synchronizeMap(hashMap);
HashTable已经被淘汰了,不要在代码中再使用它。
以下描述来自于HashTable的类注释:
If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use java.util.concurrent.ConcurrentHashMap in place of Hashtable.
简单来说就是,如果你不需要线程安全,那么使用HashMap,如果需要线程安全,那么使用ConcurrentHashMap。HashTable已经被淘汰了,不要在新的代码中再使用它。
ConcurrentHashMap实现原理:支持并发读写的HashMap,特点:读取数据时无需加锁,写数据时可以保证加锁粒度尽可能的小。内部采用“分段存储”。
二:HashMap、LinkedHashMap、TreeMap之间的区别
HashMap | LinkedHashMap | TreeMap | |
迭代顺序 | 随着时间的推移,不保证顺序将维持不变 | 插入顺序 | 根据自然顺序排序 |
Get/put remove containsKey 时间复杂度 |
O(1) | O(1) | O(log(n)) |
接口类 | Map | Map | NavigableMap Map SortedMap |
Null Values/Key |
允许 | 允许 | 仅values |
底层实现 | buckets | 双向链表+buckets | 红黑树 |
线程安全 | 不安全 | ||
能够记住元素插入的顺序 |
HashMap 是基于散列表,并且用拉链法来解决哈希冲突的。所以 HashMap 的底层数据结构是 “数组 + 链表”,即元素是链表的数组。不过当链表的元素个数超过一个阀值( static final int TREEIFY_THRESHOLD = 8; )的时候,会将链表转换为红黑树,所以如果哈希冲突多的话,数组的元素将会是红黑树。
引用: