首先是一张Java集合类的大图,基本勾勒出Java集合类之间的关系(转自百度图片)
Java集合类主要分为两类:
collection:
ArrayList:数组实现,维护 table[],get时间复杂度O(1),插入、修改、删除 需要遍历数组,O(N)
LinkedList:链表实现。get时间复杂度O(N),插入、修改、删除只需要修改指针,时间复杂度O(1)
HashSet: HashMap 实现,key= ,value=default,无序
LinkedHashSet:LinkedHashMap实现。
TreeSet:有序,采用红黑树的数据结构来存储集合元素。TreeSet支持两种排序方式: 自然排序、定制排序
map:
HashMap: 负载因子,当threshold=8 时,哈希冲突链表转为 红黑树。保证插入、遍历效率
当threashold=6时,由红黑树转为链表实现。
LinkedHashMap: 有序HashMap,通过继承Node结构,添加 prev\next指针实现。
有两种迭代顺序,插入顺序&访问顺序。
访问顺序,LRU逻辑每次访问到的元素会调整位置,加到链表的尾部。再重写removeEldest 可以实现LRU缓存。
fail-fast机制:
多线程环境下,对集合添加、修改、删除 都可能触发。
不保证一定有效。因为 modCount字段不能保证可见性。
AbstractList中实现,在迭代器中实现
private class Itr implements Iterator<E> { /** * Index of element to be returned by subsequent call to next. */ int cursor = 0; /** * Index of element returned by most recent call to next or * previous. Reset to -1 if this element is deleted by a call * to remove. */ int lastRet = -1; /** * The modCount value that the iterator believes that the backing * List should have. If this expectation is violated, the iterator * has detected concurrent modification. */ int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public E next() { checkForComodification(); try { int i = cursor; E next = get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }