HashMap:
·实现了Map接口,并继承 AbstractMap 抽象类。
·底层是散列表(哈希表)结构,以Key-Value的形式存在,存储的对象是 Entry (同时包含了 Key 和 Value) 。
·HashMap会根据hash算法来计算Key-Value的存储位置并进行快速存取。HashMap只允许一条Entry的键(Key)为null,允许 多条Entry的值(Value)为null。如果HashMap中存在键为null的键值对,那么一定在第一个桶中,即table[0]中。
·HashMap是不同步,非线性安全的。
·HashMap的构造函数中有两个重要的参数:初始容量和负载因子。容量表示散列表中桶(Bucket)的数量(即,table数组的 大小),初始容量即在创建散列表时的桶的数量,默认为16;负载因子是散列表在其容量自动增长之前所存储数据的程度,衡量一个散列 表的使用大小,负载因子越大,表示散列表的装填程度越大,反之越小。系统默认负载因子为0.75。
·HashMap 就是一个链表数组,结构如下:
每次新建一个HashMap时,都会初始化一个Entry类型的table数组。Entry为HashMap的内部类,实现了 Map.Entry 接口,其包 含了键key、值value、下一个节点next,以及hash值四个属性。
·通过HashMap存储元素时,首先调用Key的hashCode方法,此方法返回Key的哈希值,通过哈希值可以快速定位到一个桶(即,table数组的索引位置。利用了数组可以通过下标访问快速查询某一个元素),这个位置可以被称之为 bucketIndex。如 果两个对象的hashCode不同,那么equals一定为 false;否则,如果其hashCode相同,equals也不一定为 true。当hashCode 发生碰撞,这时会取出bucketIndex桶内已存储的元素,并通过 equals() 来逐个比较以判断Key是否已存在。如果已存在,则使 用新Value值替换旧Value值,并返回旧Value值;如果不存在,则存放新的键值对<Key, Value>到桶中。HashMap 都是在链表的 表头添加新元素。
·HashMap的底层数组长度总是2的n次方。
HashTable:
·底层实现是链表数组。HashMap几乎可以等价于HashTable,不同的是HashMap是非线程安全的并且可以接受null键和null值。
·Hashtable既不允许Key为null,也不允许Value为null。
·是同步、线程安全的。
·在插入Key-Value键值对的时候,HashTable是先检查是否需要扩容后插入;而HashMap是先插入后检查是否需要扩容。
·支持Iterator和Enumeration遍历。
LinkedHashMap:
·可以认为是HashMap和双向链表合二为一,是一个将所有Entry节点链入一个双向链表双向链表的HashMap,next用于维护 HashMap各个桶中的Entry链,before、after用于维护LinkedHashMap的双向链表,即Entry插入的先后顺序。
·LinkedHashMap可以很好的支持LRU算法(即Least Recently Used,最近最少使用,也就是说,当缓存满了会优先淘汰那 些最近最不常访问的数据)。
·增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。该迭 代顺序可以是插入顺序或者是访问顺序。
·LinkedHashMap最多只允许一条Entry的键为Null(多条会覆盖),但允许多条Entry的值为Null。
·不同步,非线程安全的。
·LinkedHashMap 是有序的,保存了记录的插入顺序。
TreeMap:
·底层是二叉树结构。
·可以对map集合中的键进行指定顺序的排序,是一个有序的key-value集合。
·非同步。
ConcurrentHashMap:
·ConcurrentHashMap是HashMap的一个线程安全的、支持高效并发的版本。
·ConcurrentHashMap本质上是一个Segment数组,而一个Segment实例又包含若干个桶,每个桶中都包含一条由若干个 HashEntry 对象链接起来的链表。
·在ConcurrentHashMap中,无论是读操作还是写操作都能保证很高的性能:在进行读操作时(几乎)不需要加锁,因为在HashEntry类中,key,hash和next域都被声明为final,value域被volatile所修饰,因此HashEntry对象几乎是不可变的;而在写操作时通过锁分段技术只对所操作的段加锁而不影响客户端对其它段的访问。
·既不允许key值为null,也不允许value值为null。
·在并发环境下,HashTable虽然是线程安全的,但是一般不推荐使用,因为ConcurrentHashMap比它更高效;而单线程环境下,HashMap拥有比HashTable更高的效率(HashTable的操作都是同步的,导致效率低下),所以更没必要选择它了。