常见的map类有: HashMap, ConcurrentHashMap (Jdk1.8) , LinkedHashMap, TreeMap, Hashtable。java
- 2.HashTable存储方式都是链表+数组,数组里面放的是当前hash的第一个数据,链表里面放的是hash冲突的数据 ,ConcurrentHashMap是数组+链表+红黑树.
LinkedHashMap 是基于元素进入集合的顺序或者被访问的前后顺序排序,TreeMap 则是基于元素的固有顺序 (由 Comparator 或者 Comparable 肯定)。 6. HashMap和Hashtable算法
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... } public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable { }
- HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口. 而Dictionary类是一个废弃的类。可想而知,父类被废弃,子类天然也没人用啦~~
- Hashtable比HashMap多提供了elments() 和contains() 两个方法。 elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。 contains()方法判断该Hashtable是否包含传入的value。它的做用与containsValue()一致。事实上,containsValue() 就只是调用了一下contains() 方法。
- Hashtable既不支持Null key也不支持Null value。HashMap只支持一个null key ,能够有一个或多个键的值为null.
- Hashtable是线程安全的,它的每一个方法中都加入了Synchronize方法。在多线程并发的环境下,能够直接使用Hashtable,不须要本身为它的方法实现同步
- Hashtable默认的初始大小为11,以后每次扩充,容量变为原来的2n+1。HashMap默认的初始化大小为16。以后每次扩充,容量变为原来的2倍。建立时,若是给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小。也就是说Hashtable会尽可能使用素数、奇数。而HashMap则老是使用2的幂做为哈希表的大小.
- 计算hash值的方法不一样 : Hashtable直接使用对象的hashCode. Hashtable在计算元素的位置时须要进行一次除法运算,而除法运算是比较耗时的。HashMap为了提升计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不须要作除法,只须要作位运算。位运算比除法的效率要高不少。HashMap的效率虽然提升了,可是hash冲突却也增长了。由于它得出的hash值的低位相同的几率比较高.为了解决这个问题,HashMap从新根据hashcode计算hash值后,又对hash值作了一些运算来打散数据。使得取得的位置更加分散,从而减小了hash冲突。固然了,为了高效,HashMap只作了一些简单的位处理。从而不至于把使用2的幂次方带来的效率提高给抵消掉。