Collection接口

抽象接口Collection<E>默认实现了抽象接口Iterable<E>,并包含了一些抽象方法,比如size()isEmpty()iterator()

Collection接口是集合类的根接口,Java没有提供其直接的实现类,但是让其产生了两个主要的接口ListSet

List是一个有序的集合,可以包含重复元素,通过索引访问其中的元素。
Set是一个无序的集合,不包含重复元素。

List   &   Set   &   Queue   接口

AbstractList抽象类实现了List接口。
AbstractList中有个modCount属性,表示修改次数。

protected transient int modCount = 0; 

所有使用modCount属性的都是线程不安全的。

transient关键字表示该属性不需要被序列化。
也就是说,这个字段的生命周期仅存在于调用者的内存中而不会写到磁盘里持久化。

AbstractSet抽象类实现了Set接口。

继承了AbstractSet抽象类的子类都是线程不安全的。

SortedSet抽象接口继承了Set抽象接口。

Vector   &   ArrayList   &   LinkedList

Vector和类ArrayList继承了AbstractList
Vector是线程同步和线程安全的。Vector的默认容量为10,增长率为100%。
ArrayList不是线程安全的。ArrayList的默认容量是10,增长率为100%。
ArrayListVector都是采用数组方式存储数据,所以索引查询快,插入数据慢。
Vector使用了synchronized方法所以性能上不如ArrayList

LinkedList继承抽象类AbstractSequentialList
LinkedList使用双向链表进行存储,索引查询慢,插入数据快。
LinkedList也是线程不安全的。

HashSet   &   LinkedHashSet   &   TreeSet

HashSet继承了AbstractSet抽象类。
HashSet是基于HashMap来实现的,HashSet的元素保存在HashMapkey中。
HashSet会初始化一个HashMap,并默认初始容量为16,加载因子0.75。

加载因子是hash表自动增长的系数。当数据容量达到原来的75%的时候会自动增长。
HashSet增长率为100%。

LinkedHashSet是通过继承HashSet,基于LinkedHashMap来实现的。

TreeSet继承AbstractSet抽象类,并实现了NavigableSet接口,
NavigableSet接口又继承了SortedSet接口。
TreeSet是基于TreeMap来实现的。
TreeSet支持两种排序方式,即自然排序定制排序
自然排序按元素大小以升序排序。

Map接口

抽象类AbstractMap和抽象接口SortedMap分别实现和继承了Map接口。
AbstractMap定义了两个临时属性keySetvalues

transient Set<K> keySet;
transient Collection<V> values;

分别用于保存keysvalues

继承了AbstractMap的子类都是线程不安全的。

HashMap   &   LinkedHashMap   &   TreeMap

HashMapLinkedHashMap, TreeMap都直接或间接继承于AbstractMap,所以它们都是线程不安全的。

HashMap是通过哈希表来实现数据的存储。

首先通过KeyhashCode方法找到存放位置bucketIndex,此时有三种情况:

  1. bucketIndex位置没有元素时,直接存放新的键值对。
  2. bucketIndex有元素,且和新元素相同时会替换原有元素。
  3. bucketIndex有元素,但元素不同(equals不相等),会通过链表来存储。

总之,HashMap是通过数组加链表的方式来实现的。其自增长方式和HashSet相同。

LinkedHashMap继承了HashMap。采用哈希表和双向链表来存储数据。

当排序模式accessOrdertrue时,记录访问顺序。
由于链表的增加、删除操作是常量级的,所以不会带来性能的损失。

TreeMap继承于SortedMap,并实现了NavigableMap接口。
TreeMap是通过红黑树实现的,根据Keys的升序顺序来排序。

WeakHashMap   &   Hashtable   &   ConcurrentHashMap

WeakHashMap内部是通过弱引用来管理entry的,
将一个键值对存入WeakHashMap里可能会被GC回收。
一般适用于需要缓存的场景。

Hashtable继承与Dictionary
HashtaleHashMap一样也是哈希表结构,存储键值对。
Hashtable线程同步的,其keyvalue都不允许为空。

HashMap可以通过下面的语句进行同步:

Map m = Collections.synchronizeMap(hashMap);


要使用**线程安全**的`HashMap`可以使用`Hashtable`,或者通过上面的语句进行同步,
但是这两种方式都是对整个哈希表结构做锁定操作,所以**性能不高**。
`ConcurrentHashMap`在线程安全的基础上可以高效地支持**并发**操作。
`ConcurrentHashMap`继承于`AbstractMap`,并实现了`ConcurrentMap`接口。
`Hashtable`的实现方式是锁整个`hash表`,而`ConcurrentHashMap`只锁当前需要的`bucket`。
只有在`size`等操作时才需要锁定整个表。