# ç®å½
* [0. Javaéåæ¡æ¶åå²](#Javaéåæ¡æ¶åå²)
* [1. Javaéåæ¦è¿°](#1.Javaéåæ¦è¿°)
* [Collectionéåæ¦è¿°](Collectionéåæ¦è¿°)
* [Mapéåæ¦è¿°](#Mapéåæ¦è¿°)
* [Concurrentå
ä¸çéåæ¦è¿°](#Concurrentå
ä¸çéåæ¦è¿°)
* [2. Javaéå详解](#2.Javaéå详解)
* [Collectionéåä¸å¸¸ç¨å®ç°ç±»è¯¦è§£](#Collectionéåä¸å¸¸ç¨å®ç°ç±»è¯¦è§£)
* [Iteratoræ¥å£æºç è§£æ](#Iteratoræ¥å£æºç è§£æ)
* [Collectionæ¥å£æºç è§£æ](#Collectionæ¥å£æºç è§£æ)
* [Listæ¥å£æºç è§£æ](#Listæ¥å£æºç è§£æ)
* [AbstractCollectionæ½è±¡ç±»æºç è§£æ](#AbstractCollectionæ½è±¡ç±»æºç è§£æ)
* [AbstractListæ½è±¡ç±»æºç è§£æ](#AbstractListæºç è§£æ)
* [ArrayListæºç è§£æå使ç¨](#ArrayListæºç è§£æå使ç¨)
* [Vectoræºç è§£æå使ç¨](#Vectoræºç è§£æå使ç¨)
* [Stackæºç è§£æå使ç¨](#Stackæºç è§£æå使ç¨)
* [AbstractSequentialListæ½è±¡ç±»æºç è§£æ](#AbstractSequentialListæ½è±¡ç±»æºç è§£æ)
* [LinkedListæºç è§£æå使ç¨](#LinkedListæºç è§£æå使ç¨)
* [Setæ¥å£æºç è§£æ](#Setæ¥å£æºç è§£æ)
* [AbstractSetæºç è§£æ](#AbstractSetæºç è§£æ)
* [HashSetæºç è§£æå使ç¨](#HashSetæºç è§£æå使ç¨)
* [TreeSetæºç è§£æå使ç¨](#TreeSetæºç è§£æå使ç¨)
* [Queueæ¥å£æºç è§£æ](#Queueæ¥å£æºç è§£æ)
* [Dequeæ¥å£æºç è§£æ](#Dequeæ¥å£æºç è§£æ)
* [LinkedList使ç¨](#LinkedList使ç¨)
* [Mapéåä¸å¸¸ç¨å®ç°ç±»è¯¦è§£](#Mapéåä¸å¸¸ç¨å®ç°ç±»è¯¦è§£)
* [AbstractMapæ¥å£æºç è§£æ](#AbstractMapæ¥å£æºç è§£æ)
* [HashMapæºç è§£æå使ç¨](#HashMapæºç è§£æå使ç¨)
* [WeakHashMapæºç è§£æå使ç¨](#WeakHashMapæºç è§£æå使ç¨)
* [TreeMapæºç è§£æå使ç¨](#TreeMapæºç è§£æå使ç¨)
* [Hashtableæºç è§£æå使ç¨](#Hashtableæºç è§£æå使ç¨)
* [Concurrentå
ä¸å¸¸ç¨å®ç°ç±»è¯¦è§£](#Concurrentå
ä¸å¸¸ç¨å®ç°ç±»è¯¦è§£)
* [3. éåæ¡æ¶ä¸ä½ç°ç设计模å¼åç¼ç¨è§è](#3.éåæ¡æ¶ä¸ä½ç°ç设计模å¼åç¼ç¨è§è)
* [è¿ä»£å¨æ¨¡å¼](#è¿ä»£å¨æ¨¡å¼)
* [éé
卿¨¡å¼](#éé
卿¨¡å¼)
* [4. å
¶ä»](#4.å
¶ä»)
* [fail-fastæºå¶](#fail-fastæºå¶)
* [MarkerInterface](#Marker-Interface)
* [Collectionså·¥å
·ç±»-æä½éå]()
* [Arrayså·¥å
·ç±»-æä½æ°ç»]()
* [5. åéç¹](#5.åéç¹)
* [6. Stream](#6.Stream)
* [åèèµæ](#åèèµæ)
# 0.Javaéåæ¡æ¶åå²
æèªWikipedia [Java Collection Framework](https://en.wikipedia.org/wiki/Java_collections_framework):
```
Collection implementations in pre-JDK 1.2 versions of the Java platform included few data structure classes, but did not contain a collections framework.[3] The standard methods for grouping Java objects were via the array, the Vector, and the Hashtable classes, which unfortunately were not easy to extend, and did not implement a standard member interface.[4]
To address the need for reusable collection data structures, several independent frameworks were developed,[3] the most used being Doug Lea's Collections package,[5] and ObjectSpace Generic Collection Library (JGL),[6] whose main goal was consistency with the C++ Standard Template Library (STL).[7]
```
å¯ç¥ï¼æ©æçJava Groupéè¿Array, Vector, HashTableè¿äºç±»æ¥å®ç°ï¼ä½æ¯ä»ä»¬é¾æ©å±ï¼åæå¤§ç¥ä»¬å建äºç¬ç«çJava Data Structure Frameworkï¼å¹¶ä¸å¨æ¥åè¿äºframework被buildè¿å
¥JDKä¸ï¼æ
¢æ
¢å½¢æäºJava Collection Frameworkã
# 1.Javaéåæ¦è¿°
Javaçéåç±»ä½äºjava.util.*å
ä¸ï¼å¤§ä½å为2ç±»ï¼CollectionåMapï¼å¦å¤å°±æ¯2个工å
·ç±»ãConcurrentæ¯jdk1.5å¼å
¥çï¼å¨è¿ä¹åjavaè¯è¨å
置对å¤çº¿ç¨çæ¯ææ¯è¾æéï¼ï¼ä¸»è¦ä»£ç ç±Doug Lea宿ã
## Collectionéåæ¦è¿°
1. æ¦è¿°
* Collectionå
å«3ä¸ªåæ¯
```
AbstractCollectionæ¯æ½è±¡ç±»ï¼å®ç°äºé¨åCollectionä¸çAPIï¼å¦containsï¼toArray, remove, toStringçæ¹æ³ã
```
* Queue
```
é忝ä¸ç§ç¹æ®ç线æ§è¡¨ï¼å
许å¨è¡¨ç头é¨è¿è¡å 餿ä½ï¼å¨è¡¨çå°¾é¨è¿è¡æå
¥æä½ãæ2ä¸ªç»§æ¿æ¥å£ï¼BlockingQueue(é»å¡éå)åDeque(ååéå)ãAbstractQueueæ¯æ½è±¡ç±»ï¼å®ç°äºQueueä¸ç大é¨åAPIï¼å¸¸è§å®ç°ç±»æLinkedQueueã
```
* List
```
Listæ¯ä¸ä¸ªæåºçéåï¼æ¯ä¸ªå
ç´ é½æå®çç´¢å¼ï¼ç¬¬ä¸ä¸ªå
ç´ çç´¢å¼å¼ä¸º0ãAbstractListæ¯æ½è±¡ç±»ï¼å®ç°äºListä¸ç大é¨åAPIï¼å¸¸è§å®ç°ç±»æLinkedList, ArrayList, Vector, Stackã
```
* Set
```
Setæ¯ä¸ä¸ªä¸å
许æéå¤å
ç´ çéåã AbstractSetæ¯æ½è±¡ç±»ï¼å®ç°äºSetä¸ç大é¨åAPIï¼å¸¸è§çå®ç°ç±»æHashSet, TreeSetã
```
## Mapéåæ¦è¿°
1. æ¦è¿°
* Mapå
å«1ä¸ªåæ¯
```
Mapæ¯ä¸ä¸ªæ å°æ¥å£ï¼å³key-valueçé®å¼å¯¹ãAbstractMapæ¯æ½è±¡ç±»ï¼å®ç°äºMapä¸ç大é¨åAPIï¼HashMap, TreeMap, WeakHashMapæ¯å
¶å®ç°ç±»ã
```
2. æºç é
读
`æ¥å£å®ä¹`
```java
public interface Map
```
`å¸¸ç¨æ¹æ³`
```java
abstract void clear()
abstract boolean containsKey(Object key)
abstract boolean containsValue(Object value)
abstract Set> entrySet()
abstract boolean equals(Object object)
abstract V get(Object key)
abstract int hashCode()
abstract boolean isEmpty()
abstract Set keySet()
abstract V put(K key, V value)
abstract void putAll(Map extends K, ? extends V> map)
abstract V remove(Object key)
abstract int size()
abstract Collection values()
```
```
Map æ¯ä¸ä¸ªé®å¼å¯¹(key-value)æ å°æ¥å£ãMapæ å°ä¸ä¸è½å
å«éå¤çé®ï¼æ¯ä¸ªé®æå¤åªè½æ å°å°ä¸ä¸ªå¼ã
Map æ¥å£æä¾ä¸ç§collection è§å¾ï¼å
许以é®é(keySet())ãå¼é(values())æé®-å¼(entrySet())æ å°å
³ç³»éç形弿¥çæä¸ªæ å°çå
容ã
Map æ å°é¡ºåºãæäºå®ç°ç±»ï¼å¯ä»¥æç¡®ä¿è¯å
¶é¡ºåºï¼å¦ TreeMapï¼å¦ä¸äºæ å°å®ç°åä¸ä¿è¯é¡ºåºï¼å¦ HashMap ç±»ã
Map çå®ç°ç±»åºè¯¥æä¾2ä¸ªâæ åçâæé æ¹æ³ï¼ç¬¬ä¸ä¸ªï¼voidï¼æ åæ°ï¼æé æ¹æ³ï¼ç¨äºå建空æ å°ï¼ç¬¬äºä¸ªï¼å¸¦æå个 Map ç±»ååæ°çæé æ¹æ³ï¼ç¨äºå建ä¸ä¸ªä¸å
¶åæ°å
·æç¸åé®-弿 å°å
³ç³»çæ°æ å°ãå®é
ä¸ï¼åä¸ä¸ªæé æ¹æ³å
è®¸ç¨æ·å¤å¶ä»»ææ å°ï¼çææéç±»çä¸ä¸ªçä»·æ å°ãå°½ç®¡æ æ³å¼ºå¶æ§è¡æ¤å»ºè®®ï¼å 为æ¥å£ä¸è½å
å«æé æ¹æ³ï¼ï¼ä½æ¯ JDK 䏿æéç¨çæ å°å®ç°é½éµä»å®ã
```
[Mapçä¸ç§Collectionè§å¾ä¾å MapTest01.java]
```java
// keyè§å¾
Set keys = hashMap.keySet();
Iterator iteratorKeys = keys.iterator();
while (iteratorKeys.hasNext()) {
System.out.println(iteratorKeys.next());
}
// valueè§å¾
Collection values = hashMap.values();
Iterator iteratorValues = values.iterator();
while (iteratorValues.hasNext()) {
System.out.println(iteratorValues.next());
}
// key-valueè§å¾
Set> entrySets = hashMap.entrySet();
Iterator> iteratorEntrySets = entrySets.iterator();
while (iteratorEntrySets.hasNext()) {
Entry entry = iteratorEntrySets.next();
System.out.println(String.format("key: %s, value: %s", entry.getKey(), entry.getValue()));
}
```
## Concurrentå
ä¸çéåæ¦è¿°
1. æ¦è¿°
* Concurrentä¸»è¦æ3个packageç»æ
* java.util.concurrent
```
æä¾å¤§é¨åå
³äºå¹¶åçæ¥å£åç±»ï¼å¦BlockingQueue, ConcurrentHashMap, ExecutorServiceç
```
* java.util.concurrent.atomic
```
æä¾ææçååç±»æä½ï¼å¦AtomicInteger, AtomicLongç
```
* java.util.concurrent.locks
```
æä¾éç¸å
³çç±»ï¼å¦Lock, ReentrantLock, ReadWriteLock, Confitionç
```
# 2.Javaéå详解
## Collectionéåä¸å¸¸ç¨å®ç°ç±»è¯¦è§£
### Iteratoræ¥å£æºç è§£æ
`æ»ç»`
```
iterator.remove()æ¹æ³å¿
é¡»è¦å¨è°ç¨äºnext()æ¹æ³ä¹åï¼å¦å伿¥IllegalStateExceptionã
if the next method has not yet been called, or the remove method has already been called after the last call to the next method
```
`å¸¸ç¨æ¹æ³`
```java
boolean hasNext()
E next()
void remove()
```
### Collectionæ¥å£æºç è§£æ
`æ¥å£å®ä¹`ï¼
```java
/* 说æï¼
Collectionéåç¨äºåObjectçï¼ä¸æ¯æåå¨åºç¡æ°æ®ç±»åï¼è¿æ¯ç±Collectionæ¥å£çå®ä¹å³å®çï¼ Collection
è¿æ ·å伿¥éï¼ Syntax error, insert "Dimensions" to complete ReferenceType
List ints = new ArrayList();
*/
public interface Collection extends Iterable
```
`å¸¸ç¨æ¹æ³`
```java
abstract boolean add(E object)
// addAllåæ°ä¸ºEæEçåç±»
abstract boolean addAll(Collection extends E> collection)
abstract void clear()
abstract boolean contains(Object object)
abstract boolean containsAll(Collection> collection)
abstract boolean equals(Object object)
abstract int hashCode()
abstract boolean isEmpty()
abstract Iterator iterator()
abstract boolean remove(Object object)
abstract boolean removeAll(Collection> collection)
abstract boolean retainAll(Collection> collection)
/*
* Returns the number of elements in this collection. If this collection
* contains more than Integer.MAX_VALUE elements, returns
* Integer.MAX_VALUE.
* Integer.MIN_VALUEæ¯-ï¼2ç31次æ¹ï¼ï¼Integer.MAX_VALUEæ¯2ç31次æ¹å1
*/
abstract int size()
abstract T[] toArray(T[] array)
abstract Object[] toArray()
```
### Listæ¥å£æºç è§£æ
`æ»ç»`
```
Listæ¯æåºçï¼æ¯æéæºè®¿é®ï¼éè¿ç´¢å¼ä¸æ 访é®ï¼
Listå
许éå¤çå¼ï¼åå æ¯å®çæ°æ®å卿¹å¼ï¼
```
`å¸¸ç¨æ¹æ³`
```java
boolean add(E)
void add(int, E)
boolean addAll(int, Collection extends E>)
boolean addAll(Collection extends E>)
void clear()
boolean contains(Object) //AbstractCollectionä¸éè¿iteratorè¿ä»£éå夿 ArrayListä¸éè¿è°ç¨indexOf(o) >= 0 æ¥å¤ææ¯å¦å
å«
boolean containsAll(Collection>)
boolean equals(Object)
E get(int)
int hashCode()
int indexOf(Object)
boolean isEmpty()
Iterator iterator()
int lastIndexOf(Object)
ListIterator listIterator()
ListIterator listIterator(int)
E remove(int)
boolean remove(Object)
boolean removeAll(Collection>)
boolean retainAll(Collection> a) // b.retainAll(a) ç§»é¤b䏿èa䏿²¡æçææå
ç´ ï¼æä»¥ç»ææ¯açåé
E set(int, E)
int size()
List subList(int, int)
Object[] toArray()
T[] toArray(T[])
```
```java
ListIterator.java
boolean hasNext()
boolean hasPrevioud()
E next()
E previous()
int nextIndex()
int previousIndex()
```
#### AbstractCollectionæ½è±¡ç±»æºç è§£æ
`æ»ç»`
```
AbstractCollectionæ¯ä¸ªæ½è±¡ç±»ï¼ç»§æ¿èªCollectionæ¥å£ï¼å¹¶å®ç°äºå
¶ä¸çæ¹æ³ï¼åæ¶æ·»å äºtoString()æ¹æ³
```
`å¸¸ç¨æ¹æ³`
```java
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // å8çåå æ¯æäºVMsåå¨äºæ°æ®çheader
private static T[] finishToArry(T[] r, Iterator> it) // ç¨äºå°éå转æ¢ä¸ºæ°ç»
private static int hugeCapacity(int minCapacity) // ç¨äºfinishToArry
boolean add(E e) // æªå®ç°
boolean addAll(int index, Collection extends E> c) // æªå®ç°
void clear()
boolean contains(Object o) // è¿ä»£éå夿
boolean containsAll(Collection> c) // for循ç¯éåcï¼ç¶åéè¿è°ç¨contains夿
boolean isEmpty() // éè¿å¤æsize()==0ï¼size()æªå®ç°
Iterator iterator() // æªå®ç°
boolean remove(Object o) //è¿ä»£å¨éåå é¤
boolean removeAll(Collection> c)
boolean retainAll(Collection> c)
int size();
Object[] toArray()
T[] toArray(T[])
String toString() // è¿ä»£éåéåï¼éè¿StringBuilderæ¥æ¶ç»åè¾åº
```
#### AbstractListæºç è§£æ
`æ»ç»`
```
AbstractList䏿Itr(ç»§æ¿Iterator)åListItr(ç»§æ¿ListIterator)两个å
é¨ç±»
å¨è¿ä»£éåè¿ç¨ä¸ï¼å¦æåºç°å¯¹éåçåçè¡ä¸ºï¼list.remove(obj)ï¼ï¼ä¼æ¥åºConcurrentModificationExceptionã
AbstractListä¸ä»ç¶æ²¡æå®ç°addæ¹æ³
```
```java
// listè°ç¨removeæ¹æ³ä¼å¯¼è´modCountç弿¹å
private void fastRemove(int index) {
modCount++;
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
}
// éè¿è°ç¨iterator.remove()å¯ä»¥ä¿è¯ä¸ä¼æ¥ConcurrentModificationException
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();
}
```
##### ArrayListæºç è§£æå使ç¨
`æ»ç»`
1. ArrayListæ¯ä¸ä¸ªæ°æ®éåï¼ç¸å½äºä¸ä¸ªå¨ææ°ç»(Object[] elementData)ãä¸Javaä¸çæ°æ®ç¸æ¯ï¼å®ç容éè½å¨æå¢é¿ï¼é»è®¤é¿åº¦æ¶10(DEFAULT_CAPACITY)ï¼æ©å®¹æ¶æ°ç容é=åå§å®¹é + åå§å®¹é>>1
2. ArrayListå®ç°äºRandomAccessæ¥å£ï¼Marker Interfaceï¼ï¼åç±äºå
¶æ°æ®ä»¥æ°æ®åå¨ï¼å æ¤æ¯æå¿«ééæºæ¥æ¾ï¼ä½æ¯ä¿®æ¹åå 餿çä¸é«
```java
// Collectionsä¸éè¿RandomAccessæ¥å£å¤æ
public static
int binarySearch(List extends Comparable super T>> list, T key) {
if (list instanceof RandomAccess || list.size() extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable
```
1. Vectoræ¯ä¸ä¸ªç¢ééåï¼æ¯ææ¯æ¬çæ·»å ãä¿®æ¹ãå é¤ãéåçåè½
2. Vectorå®ç°äºRandomAccessæ¥å£ï¼å³æ¯æéæºè®¿é®åè½ï¼get(int index)ï¼
3. Vectorä¸çpublic API齿¯å äºsynchronizedå
³é®åæ¥ä¿è¯çº¿ç¨å®å
¨
##### Stackæºç è§£æå使ç¨
`æ»ç»`
```
Stackæ¯æ ï¼ç¹æ§æ¯å
è¿ååº(FILO, First In Last Out)
Stackæ¯ç»§æ¿èªVectorï¼ä¹æ¯éè¿æ°æ®å®ç°ç
```
`å¸¸ç¨æ¹æ³`
```java
Object push(Object element) // æå¯¹è±¡åå
¥å æ
Object pop() // ç§»é¤å æ é¡¶é¨å¯¹è±¡ï¼å¹¶ä½ä¸ºæ¤æ¹æ³çè¿åå¼è¿å该对象
Object peek() // æ¥çå æ é¡¶é¨ç对象ï¼ä½ä¸ä»å æ ä¸ç§»é¤å®
```
#### AbstractSequentialListæ½è±¡ç±»æºç è§£æ
`æ»ç»`
```
è¿ä¸ªæ½è±¡ç±»æ²¡ä»ä¹ç¹å«
```
##### LinkedListæºç è§£æå使ç¨
`æ»ç»`
```java
public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, Serializable {}
```
```
LinkedListå®ç°äºDequeæ¥å£ï¼è½å¯¹å®è¿è¡ååå表æä½ï¼ä¹å°±æ¯è¯´é¡ºåºè®¿é®ä¼é叏髿ï¼éæºè®¿é®æçæ¯è¾ä½
LinkedList䏿¯çº¿ç¨å®å
¨çï¼å¯ä»¥éè¿List list = Collections.synchronizedList(new LinkedList(...))æ¥è½¬æ¢ï¼ä¸è¿LinkedListçæ°æ®ç±»åä¼ä¸¢å¤±
LinkedListä¸ä½¿ç¨Node对象æ¥å卿°æ®
```
`å¸¸ç¨æ¹æ³`
```java
boolean add(E element) // offerå±äº offer in interface Deque, add å±äº add in interface Collection
void(int index, E element) // 夿index==sizeï¼=å°±linkLast, or linkBefore
void addFirst(E element)
void addLast(E element)
void clear() // æ¸
ç©ºï¼æ³¨æGC
Object clone() // æµ
æ·è´ shallow copy
Iterator descendingIterator() // åçè¾åº
E element() // è·å第ä¸ä¸ªå
ç´
E get(int index)
E getFirst();
E getLast();
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator listIterator(int index)
boolean offer(E element) // offerå±äº offer in interface Deque, add å±äº add in interface Collection
boolean offerFirst(E element)
boolean offerLast(E element)
E peek() // è¿åé¾è¡¨ä¸ç第ä¸ä¸ªå
ç´ ï¼å¹¶ä¸ä¸ä¼ç§»é¤
E peekFirst() // åpeek没å¥åºå«
E peekLast()
E poll() // è¿åé¾è¡¨ä¸ç第ä¸ä¸ªå
ç´ ï¼å¹¶ä¸ä¼ç§»é¤æ
E pollFirst() // é¾è¡¨ä¸ºç©ºæ¶ä¼è¿ånull
E pollLast()
E pop() // é¾è¡¨ä¸ºç©ºæ¶ä¼æ¥NoSuchElementExceptionï¼è¿å°±æ¯åºå«
void push(E e) // æ·»å å°é¾è¡¨ç第ä¸ä¸ªå
ç´
E removeï¼ï¼ // å é¤ç¬¬ä¸ä¸ªå
ç´
E remove
E set(int index, E element) // æ¿æ¢æå®ä½ç½®çå
ç´
```
LinkedListå¯ä»¥ä½ä¸ºFIFOçéåï¼ä½¿ç¨å¦ä¸æ¹æ³ï¼
```java
// Queue
boolean add(e) // addæ¯offerçåºå«å¨äºaddæ¶å¦æcapacityè¶
äºï¼ä¼æ¥éï¼èofferä¸ä¼
boolean offer(e)
E remove() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼å¹¶ä¸å é¤ï¼å¦æéåä¸ºç©ºï¼æ¥NoSuchElementException
E poll() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼å¹¶ä¸å é¤ï¼å¦æéå为空ï¼è¿ånull
E element() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼ä¸å é¤ï¼å¦æéåä¸ºç©ºï¼æ¥NoSuchElementException
E peek() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼ä¸å é¤ï¼å¦æéå为空ï¼è¿ånull
```
LinkedListä¹å¯ä»¥ä½ä¸ºFILOçæ ï¼ä½¿ç¨å¦ä¸æ¹æ³ï¼
```java
push(e)
pop()
peek()
```
`æºç è§£æ`
```java
private static class Node {
E item;
Node next;
Node prev;
Node(Node prev, E element, Node next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
```
LinkedListå¨å
é¨å®ä¹äºä¸ä¸ªå«åNodeç±»åçéæå
é¨ç±»ï¼Nodeå°±æ¯ä¸ä¸ªèç¹ï¼é¾è¡¨ä¸çèç¹ï¼æ3ä¸ªå±æ§ã
```java
// 3ä¸ªå±æ§
transient int size = 0; // éåé¾è¡¨å
èç¹æ°é
transient Node first; // é¦èç¹
transient Node last; // å°¾èç¹
```
```java
// Appends the specified element to the end of this list
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++;
}
...
```
### Setæ¥å£æºç è§£æ
`æ»ç»`
```
Setæ¯ç»§æ¿èªCollectionçæ¥å£ï¼æ¯ä¸ä¸ªä¸å
许æéå¤å
ç´ çç»åã
AbstractSetæ¯ä¸ä¸ªæ½è±¡ç±»ï¼ç»§æ¿èªAbstractCollectionï¼AbstractCollectionå®ç°äºSetä¸çç»å¤§é¨å彿°
HashSetåTreeSetæ¯Setç两个å®ç°ç±»
HashSetä¾èµHashMapï¼å®å®é
䏿¯éè¿HashMapå®ç°çï¼HashSetä¸çå
ç´ æ¯æ åºç
TreeSetä¾èµTreeMapï¼å®å®é
䏿¯éè¿TreeMapå®ç°çï¼TreeSetä¸çå
ç´ æ¯æåºç
```
#### AbstractSetæºç è§£æ
AbstractSet没æå¯¹Setåå¤å°çå®ç°ï¼å
¶ç»§æ¿äºAbstractCollection
`æºç è§£æ`
```java
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Collection c = (Collection) o;
if (c.size() != size())
return false;
try {
return containsAll(c);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
```
##### HashSetæºç è§£æå使ç¨
`æ»ç»`
```
HashSetæ¯ä¸ä¸ªæ²¡æéå¤å
ç´ çéåï¼å®æ¯ç±HashMapå®ç°çï¼HashMapä¸keyä¸è½éå¤ï¼ï¼ä¸ä¿è¯å
ç´ ç顺åºï¼èä¸HashSetå
许使ç¨nullå
ç´ ã
HashSetæ¯é忥çï¼å æ¤å¦æå¤çº¿ç¨åæ¶è®¿é®ä¸ä¸ªHashSetï¼èå
¶ä¸è³å°æä¸ä¸ªçº¿ç¨ä¿®æ¹äºè¯¥HashSetçè¯ï¼é£ä¹éè¦ä¿æå¤é¨åæ¥ï¼é常å¯ä»¥å¯¹è¯¥Setç对象å°è£
æ¥å®æåæ¥æä½ï¼ä¹å¯ä»¥ä½¿ç¨Collections.synchronizedSetæ¹æ³æ¥å®æã
HashSetæ¯éè¿Iteratorè¿ä»£éåç
```
`å¸¸ç¨æ¹æ³`
```java
HashSet()
HashSet(int initialCapacity)
HashSet(int initialCapacity, float loadFactor)
HashSet(int initialCapacity, float loadFactor, boolean dummy)
HashSet(Collection extends E> c)
boolean add(E)
void clear()
Object clone()
boolean contains(Object object)
boolean isEmpty()
Iterator iterator()
boolean remove(Object object)
int size()
```
`æºç è§£æ`
```java
private transient HashMap map;
// Dummy value to associate with an Object in the backing Map
private transient HashMap map;
// newä¸ä¸ªHashSetçæ¶åå
¶å®æ¯newçHashMap
public HashSet() {
map = new HashMap<>();
}
/*
* Constructs a new set containing the elements in the specified
* collection. The HashMap is created with default load factor
* (0.75) and an initial capacity sufficient to contain the elements in
* the specified collection.
*
* @param c the collection whose elements are to be placed into this set
* @throws NullPointerException if the specified collection is null
è°ç¨çæ¯Math.max((int) (c.size()/.75f) + 1, 16), æ¯è¾(int) (c.size()/.75f) + 1å16ç大å°
éæ©å è½½å å为.75æ¯åºäºæççèèï¼æ¶é´åç©ºé´ææ¬ï¼
妿HashMapçå½åsize >= threadhold(ä¹å°±æ¯Math.max((int) (c.size()/.75f) + 1, 16))ï¼é£ä¹å¨æ·»å å
ç´ çæ¶åï¼sizeæ¯è¦ç¿»åçï¼ä¹å°±æ¯è¯´HashMapç容éå¿
é¡»æ¯2çææ°ï¼å
·ä½è·è¸ªputæ¹æ³
*/
public HashSet(Collection extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
/*
ä¼éæ°è®¡ç®capacity int capacity = roundUpToPowerOf2(toSize);
roundUpToPowerOf2ï¼toSizeï¼
return number >= MAXIMUM_CAPACITY
? MAXIMUM_CAPACITY
: (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
*/
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i); // è¿éè°ç¨addEntry
return null;
}
// è¿ä»£éåçæ¶åéåçæ¯key
public Iterator iterator() {
return map.keySet().iterator();
}
// addçæ¶åæå
¥çæ¯key
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
/** æµ
æ·è´
* Returns a shallow copy of this HashSet instance: the elements
* themselves are not cloned.
*
* @return a shallow copy of this set
*/
public Object clone() {
try {
HashSet newSet = (HashSet) super.clone();
newSet.map = (HashMap) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
/**
* Save the state of this HashSet instance to a stream (that is,
* serialize it).
*
* @serialData The capacity of the backing HashMap instance
* (int), and its load factor (float) are emitted, followed by
* the size of the set (the number of elements it contains)
* (int), followed by all of its elements (each an Object) in
* no particular order.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject();
// Write out HashMap capacity and load factor
s.writeInt(map.capacity());
s.writeFloat(map.loadFactor());
// Write out size
s.writeInt(map.size());
// Write out all elements in the proper order.
for (E e : map.keySet())
s.writeObject(e);
}
/**
* Reconstitute the HashSet instance from a stream (that is,
* deserialize it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
// Read in HashMap capacity and load factor and create backing HashMap
int capacity = s.readInt();
float loadFactor = s.readFloat();
map = (((HashSet)this) instanceof LinkedHashSet ?
new LinkedHashMap(capacity, loadFactor) :
new HashMap(capacity, loadFactor));
// Read in size
int size = s.readInt();
// Read in all elements in the proper order.
for (int i=0; i extends AbstractSet implements NavigableSet, Cloneable, Serializable {}
```
```
TreeSetæ¯ä¸ä¸ªæåºå¹¶ä¸æ²¡æéå¤çSetéåï¼å®æ¯éè¿TreeMapå®ç°ç
TreeSetå®ç°äºNavigableSetæ¥å£ï¼å æ¤å
¶æ¯æéåçå¯¼èªæ¹æ³ï¼å¦lowerï¼è¿åå°äºï¼, floorï¼è¿åå°äºçäºï¼, ceilingï¼è¿å大äºçäºï¼, higherï¼è¿å大äºï¼ï¼å¦æä¸åå¨è¿æ ·çå
ç´ ï¼åè¿ånull
```
`æºç è§£æ`
```java
// The backing map. æ°æ®åå¨å¨è¿ä¸ªå¯¹è±¡ä¸
private transient NavigableMap m;
private static final Object ORESENT = new Obect();
public TreeSet() {
this(new TreeMap());
}
public TreeSet(Collection extends E> c) {
this();
addAll(c);
}
// 带æ¯è¾å¨çæé 彿°
public TreeSet(Comparator super E> comparator) {
this(new TreeMap<>(comparator));
}
TreeSet(NavigableMap m) {
this.m = m;
}
public TreeSet(SortedSet s) {
this(s.comparator());
addAll(s);
}
// è¿ä»£å¨
public Iterator iterator() {
return m.navigableKeySet().iterator();
}
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
/* Returns the least key greater than or equal to the given key, or {@code null} if there is no such key.
è¿åéåä¸å¤§äºçäºç»å®å
ç´ çæå°å
ç´ ï¼æç¹ç»ï¼è¿æ¯è±ææ¯è¾å¥½çè§£
*/
public E ceiling(E e) {
return m.ceilingKey(e);
}
/*
Returns the least key strictly greater than the given key, or {@code null} if there is no such key.
è¿åéåä¸å¤§äºç»å®å
ç´ çæå°å
ç´
*/
public E higher(E e) {
return m.higherKey(e);
}
/*
Returns the greatest key strictly less than the given key, or {@code null} if there is no such key.
è¿åéåä¸å°äºç»å®å
ç´ çæå¤§å
ç´
*/
public E lower(E e) {
return m.lowerKey(e);
}
/*
Returns the greatest key less than or equal to the given key, or {@code null} if there is no such key.
è¿åå ä½ä¸å°äºæçäºç»å®å
ç´ çæå¤§å
ç´
*/
public E floor(E e) {
return m.floorKey(e);
}
```
### Queueæ¥å£æºç è§£æ
`æºç åæ`
```java
public interface Queue extends Collection {
boolean add(e) // addæ¯offerçåºå«å¨äºaddæ¶å¦æcapacityè¶
äºï¼ä¼æ¥éï¼èofferä¸ä¼
boolean offer(e)
E remove() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼å¹¶ä¸å é¤ï¼å¦æéåä¸ºç©ºï¼æ¥NoSuchElementException
E poll() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼å¹¶ä¸å é¤ï¼å¦æéå为空ï¼è¿ånull
E element() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼ä¸å é¤ï¼å¦æéåä¸ºç©ºï¼æ¥NoSuchElementException
E peek() // è¿åéåç第ä¸ä¸ªå
ç´ ï¼ä¸å é¤ï¼å¦æéå为空ï¼è¿ånull
}
```
### Dequeæ¥å£æºç è§£æ
`æ»ç»`
```
ååéåï¼ç»§æ¿èªQueueæ¥å£ï¼åæ¶æä¾äºä¸°å¯çæä½éåçæ¹æ³ï¼å
·ä½å¯åèLinkedListæºç åæ
```
##### LinkedList使ç¨
Go to here [LinkedListæºç è§£æå使ç¨](#LinkedListæºç è§£æå使ç¨)
## Mapéåä¸å¸¸ç¨å®ç°ç±»è¯¦è§£
`æ»ç»`
```
Mapæ¯ä¸ä¸ªé®å¼å¯¹çæ¥å£ï¼Map
AbstractMapå®ç°äºMapæ¥å£ï¼ä½æ¯å 乿²¡æå®ç°Mapä¸çæ¹æ³ï¼ä½æ¯å´å®ä¹äºä¸äºå¸¸ç¨çæ¹æ³
SortedMapç»§æ¿èªMapæ¥å£ï¼SortedMapä¸çå
å®¹æ¯æåºäºçé®å¼å¯¹ï¼æåºçæ¹æ³æ¯éè¿æ¯è¾å¨ï¼Comparatorï¼
NavigableMapæ¯ç»§æ¿èªSortedMapçæ¥å£ï¼ç¸å¯¹äºSortedMapï¼NavigableMapæä¸ç³»åçå¯¼èªæ¹æ³ï¼å¦è·å>, <, >=, <=çå¼
TreeMapç»§æ¿èªAbstractMapï¼å®ç°äºNavigableMapæ¥å£ï¼å æ¤ï¼TreeMapæ¯æåºçé®å¼å¯¹
HashMapç»§æ¿èªAbstractMapï¼æ²¡æå®ç°SortedMapï¼å æ¤ï¼HashMap䏿¯æåºçé®å¼å¯¹ãHashMapå
许æå
¥keyæè
value为nullçå
ç´
Hashtable没æç»§æ¿èªAbstractMapï¼ç»§æ¿çæ¯Dictionaryï¼å®ç°äºMapæ¥å£ï¼å æ¤ï¼Hashtableæ¯æ åºçé®å¼å¯¹ãHashtableä¸å
许æå
¥keyæè
value为nullçå
ç´ ï¼Hashtableçæ¹æ³å äºsynchronizedå
³é®åï¼ä¿è¯äºçº¿ç¨çå®å
¨ã
WeakhashMapç»§æ¿èªAbstractMapï¼å¤§è´æ¥è¯´å®ä¸HashMapçé®ç±»åä¸åï¼WeakHashMap使ç¨çæ¯âå¼±é®âï¼å
åä¸è¶³æ¶ä¼è¢«GCæ¶æï¼
```
`æºç åæ`
```java
void clear();
boolean containsKey(Object key);
boolean containsValue(Object value);
Set entrySet();
boolean equals(Object o);
V get(Object obj);
boolean isEmpty();
Set keySet(); // è¿åkeyçéåï¼å 为keyä¸éå¤ï¼æä»¥ç¨Setæ¥æ¶
V put(K k, V v);
void putAll(Map extends K, ? extends V> m);
V remove(Object key);
int size();
Collections values(); // è¿åvalueçç»åï¼valuesæ¯éå¤ç
// Mapä¸è¿æä¸ä¸ªå
ç½®çæ¥å£ Map#entrySet()
interface Entry {
K getKey();
V getValue();
int hashCode();
V setValue(V);
boolean equals(Object obj)
}
```
#### AbstractMapæ¥å£æºç è§£æ
AbstractMapå®ç°äºMapæ¥å£ï¼å®ç°äºä¸äºéç¨çæ¹æ³
`æºç è§£æ`
```java
// å·§å¦çåæ³
private static boolean eq(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
```
##### HashMapæºç è§£æå使ç¨
`å®ä¹`
```java
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {}
```
`æé 彿°`
```java
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); // initial capacity=16 load factor=0.75
}
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {}
public HashMap(Map extends K, ? extends V> m) {}
```
`public method`
```java
void clear()
Object clone()
boolean containsKey(Object key)
boolean containsValue(Object value)
Set> entrySet()
V get(Object obj)
boolean isEmpty()
Set keySet()
V put(K k, V v)
void putAll(Map extends K, ? extends V>)
V remove(Object obj)
int size()
String toString()
Collection values()
```
`æºç è§£æ`
```java
// æ°æ®åå¨å¨è¿éï¼ä¸ä¸ªå«tableçåéä¸
transient Entry[] table = (Entry[]) EMPTY_TABLE;
// çä¸Entryçå®ä¹ï¼æ¯ä¸ä¸ªEntryæ¯ä¸ä¸ªååé¾è¡¨
static class Entry implements Map.Entry {
final K key;
V value;
Entry next;
int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry n) {
value = v;
next = n;
key = k;
hash = h;
}
}
// æ¥ä¸æ¥æä»¬å°±çä¸HashMapæ¯å¦ä½åå¨å¼çãæä»¬é½ç¥éHashMapä¸ä½¿ç¨put(K k, V v)æ¥åå¨å¼
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value); // åå¨null keyï¼ç´æ¥è°ä»·å°table[0]ä¸
int hash = hash(key); // é¦å
æ ¹æ®key计ç®åºhashå¼
int i = indexFor(hash, table.length); // åæ ¹æ®hashå¼ï¼è®¡ç®åºæ°æ®ç´¢å¼ï¼ä¹å°±æ¯Entryå¨tableä¸çç´¢å¼
// ç¶åæ ¹æ®ç´¢å¼æ¾å°tableä¸çEntryï¼æ¯ä¸ä¸ªååé¾è¡¨ï¼ï¼éè¿e.next循ç¯éåå项é¾è¡¨
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
// å°key䏿¯ä¸ä¸ªEntryçkeyè¿è¡å¯¹æ¯ï¼åå¸å¼è¿è¡å¯¹æ¯ï¼å¦ækeyå·²ç»åå¨å°±æ¿æ¢ææ§å¼ï¼å¹¶ä¸è¿åæ§å¼
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
// 妿keyä¸åå¨Entryé¾è¡¨ä¸ï¼å°±æ°å»ºä¸ä¸ªEntry
addEntry(hash, key, value, i);
return null;
}
// addEntryçæ¶åç´¢å¼å¼ä¸º0ï¼
private V putForNullKey(V value) {
for (Entry e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
// å¨tableä¸çindexæ¯0ï¼æä»¥HashMapæä¸ä¸ªåºå®åå¨key为nullçå¼ï¼æ¤ä½ç½®ä¸ºtableç第ä¸ä¸ªä½ç½®
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length); // sizeç¿»å
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}
// æå
¥nullå¼ä¹åï¼å¾ªç¯è°ç¨Map#putæ¹æ³æå
¥1-18
::hash:: 0 ::key:: null ::value:: 1 ::bucketIndex:: 0
::hash:: 50 ::key:: 1 ::value:: value 1 ::bucketIndex:: 2
::hash:: 49 ::key:: 2 ::value:: value 2 ::bucketIndex:: 1
::hash:: 48 ::key:: 3 ::value:: value 3 ::bucketIndex:: 0
::hash:: 55 ::key:: 4 ::value:: value 4 ::bucketIndex:: 7
::hash:: 54 ::key:: 5 ::value:: value 5 ::bucketIndex:: 6
::hash:: 53 ::key:: 6 ::value:: value 6 ::bucketIndex:: 5
::hash:: 52 ::key:: 7 ::value:: value 7 ::bucketIndex:: 4
::hash:: 59 ::key:: 8 ::value:: value 8 ::bucketIndex:: 11
::hash:: 58 ::key:: 9 ::value:: value 9 ::bucketIndex:: 10
::hash:: 1650 ::key:: 10 ::value:: value 10 ::bucketIndex:: 2
::hash:: 1614 ::key:: 11 ::value:: value 11 ::bucketIndex:: 14
::hash:: 1615 ::key:: 12 ::value:: value 12 ::bucketIndex:: 15
::hash:: 1612 ::key:: 13 ::value:: value 13 ::bucketIndex:: 12
::hash:: 1613 ::key:: 14 ::value:: value 14 ::bucketIndex:: 13
::hash:: 1610 ::key:: 15 ::value:: value 15 ::bucketIndex:: 10
::hash:: 1611 ::key:: 16 ::value:: value 16 ::bucketIndex:: 11
::hash:: 1608 ::key:: 17 ::value:: value 17 ::bucketIndex:: 8
```
`æ»ç»`
```
HashMapç»§æ¿äºAbstractMapç±»ï¼å®ç°äºMapæ¥å£ãMapæ¯"key-valueé®å¼å¯¹"æ¥å£ï¼AbstractMapå®ç°äº"é®å¼å¯¹"çéç¨å½æ°æ¥å£ã
HashMapæ¯éè¿"æé¾æ³"å®ç°çåå¸è¡¨ãå®å
æ¬å 个éè¦çæååéï¼table, size, threshold, loadFactor, modCountã
tableæ¯ä¸ä¸ªEntry[]æ°ç»ç±»åï¼èEntryå®é
ä¸å°±æ¯ä¸ä¸ªååé¾è¡¨ãåå¸è¡¨ç"key-valueé®å¼å¯¹"齿¯åå¨å¨Entryæ°ç»ä¸çã
sizeæ¯HashMapç大å°ï¼å®æ¯HashMapä¿åçé®å¼å¯¹çæ°éã
thresholdæ¯HashMapçéå¼ï¼ç¨äºå¤ææ¯å¦éè¦è°æ´HashMapç容éãthresholdçå¼="容é*å è½½å å"ï¼å½HashMapä¸å卿°æ®çæ°éè¾¾å°thresholdæ¶ï¼å°±éè¦å°HashMapç容éå åã
ããloadFactorå°±æ¯å è½½å åã
ããmodCountæ¯ç¨æ¥å®ç°fail-fastæºå¶çã
```
##### WeakHashMapæºç è§£æå使ç¨
`å®ä¹`
```java
public class WeakhashMap extends AbstractMap implements Map {}
```
`æé 彿°åHashMap类似`
```java
public WeakHashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public WeakHashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public WeakHashMap(int initialCapacity, float loadFactor) {}
public WeakHashMap(Map extends K, ? extends V> m) {}
```
`éè¦åé`
```java
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private static final int MAXIMUM_CAPACITY = 1 << 30;
private static final float DEFAULT_LOAD_FACTOR = 0.75F;
Entry[] table;
private int size;
private int threshold;
private final float loadFactor;
private final ReferenceQueue