Map
-
HashMap
- 默认容量是16,负载因子为0.75.可以通过构造函数自定义。当数组长度超过 容量*负载 因子时,会进行扩容,扩容2倍。
- 底层采用数组+单项链表的方式实现。
即:调用put方法时,会计算key的hash值,然后对hash进行取模获取要插入的数组位置i。如果该位置已经存在链表,则会遍历链表,比较是否有相同的元素(hash相等就再比较equals),有就覆盖,没有就插入在链表头部。 - 如果链表的长度超过8且数组的长度超过64则会把超过8的链表转化为红黑树,以提高查询效率。
- HashMap中的键值是没有顺序的,因为hash是随机的。
- HashMap中键和值都可以为null。
- HashMap是非线程安全的,HashTable和HashMap底层实现类似,其不允许key或者值是null。HashTable加了synchronized实现了线程安全,效率并不好,如果需要在高并发下使用Map,推荐使用ConcurrentHashMap。
-
TreeMap
可以进行排序,TreeMap的实现基础是排序二叉树
-
LinkedHashMap
可以保持添加的顺序
Set
Set是没有重复元素,且不保证顺序的容器接口。
-
HashSet
只需要明白,HashSet底层使用的是HashMap。
private transient HashMap<E,Object> map;
Map有键和值,而HashSet其实是只有key,值是一个固定值。可以通过源码看出。
Hash中定义了一个final Object类型的PRESENT常量。private static final Object PRESENT = new Object();
然后在add方法中可以看到,存入的value每次都是这个PRESENT
public boolean add(E e) { return map.put(e, PRESENT)==null; }
-
LinkedHashSet
可以保持添加的顺序
-
TreeSet
可以对元素进行排序