先上类结构图
Collection血统
Collection接口有三个重要的分支: Set、Queue、List
1. Set接口
表示唯一集合,不能保证有顺序。
AbstracSet抽象类,提供了基础实现,HashSet,KeySet,TreeSet都是继承该抽象类。
Set接口下还有一个分支SortedSet接口,表示有序唯一集合。
附:HashSet不是线程安全,如果多线程环境下需要额外做同步操作,可以使用 Collections.synchronizedSet进行包装。
2. List接口
表示一个有顺序的集合,集合元素可以重复。
其中LIFO(后进先出)数据结构 Stack类 也是属于List接口。
附:ArrayList类不是线程安全,如果多线程环境下需要额外做同步操作,可以使用
Collections.synchronizedList进行包装。
LinkedList 与 ArrayList的区别
两个类都实现了List接口, ArrayList用于查询,LinkedList用于频繁删除添加的场景。
- ArrayList
ArrayList每次add,remove都会重新通过Arrays.copyOf进行创建新的数组对象:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
Arrays.copyOf方法:
public static T[] copyOf(U[] original, int newLength, Class extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
//重新分配内存
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
- LinkedList
LinkedList是链表数据结构,每个节点都存放下一个节点的引用,索引可以避免 ArrayList删除/添加时执行“重新分配内存”的操作。
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
详细区别:
https://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651481030&idx=2&sn=7f35bf0eeefeb2191c86d2dfb4b55b70&chksm=bd250fb98a5286afe0ae6f65bffaf2ab276b3be4fbf4084287d89d5e3de55a7db89f428bd6d9&mpshare=1&scene=1&srcid=0414ToDxkiBAJUnUXcFO9jGw&key=a26753775bc5a4cc886706972508c30fe7c5a3b8a77e8c8e9d6bb83d55a9559f8184d5a77875b7adbacecba11b195ddf797735f6d32cb28cadb8594048c50c20b51b0244f182d670d8743a3dadc591e8&ascene=0&uin=MjI2MDQwMjA0Mg%3D%3D&devicetype=iMac+MacBookPro9%2C2+OSX+OSX+10.11.6+build(15G1421)&version=12020110&nettype=WIFI&lang=zh_CN&fontScale=100&pass_ticket=q20tAdbWNXDppQJqwnYTu9QyYN5IsbWjtzeJWCs%2FC6mKPuopT%2BVn9Ly8m4lzWp3r
3. Queue接口
表示FIFO(先进先出)数据结构的队列。
Queue接口有两个重要分支: BlockingQueue 和 Deque。
3.1 BlockingQueue
阻塞队列,用于多线程环境,属于线程安全队列。
例如创建Java线程池执行对象(实现Executor接口对象)时也需要一个BlockQueue。
3.2 Deque
双向队列,除了 满足了Queue的 FIFO特性,也满足LIFO,可以从两端进行操作。
所以链表结构 LinkedList也是有这两个特性。
Map血统
主要有几个常用的类, HashMap, ConcurrentHashMap,TreeMap,HashTable