java collection相当于c++中的stl,是最常用的几个容器,作为一个靠java吃饭的程序员必须熟悉。我将以此文作为目录,将常用的collection都整理一下。
整个java的collection框架由三大部分组成
- interface:所有的接口
- implementation:所有的实现
- algorithm:static的算法
接口(interface):
java collection中的接口可以分为两块,java.util.Collection 和 java.util.Map,两块的一些常用的类可以由下图概况。图中需要注意的一点是Deque实际上是Queue的subinterface
java.util.Collection:
- java.util.Set
- java.util.SortedSet
- java.util.NavigableSet
- java.util.Queue
- java.util.concurrent.BlockingQueue
- java.util.concurrent.TransferQueue
- java.util.Deque
- java.util.concurrent.BlockingDeque
java.util.Map:
- java.util.SortedMap
- java.util.NavigableMap
- java.util.concurrent.ConcurrentMap
- java.util.concurrent.ConcurrentNavigableMap
实现(implementation):
实现的命名按照如下格式 <Implementation-style><Interface>, 比如 HashSet。通用的实现如下表,以下全部都是非线程安全的(unsynchronized)
Interface | Hash Table | Resizable Array | Balanced Tree | Linked List | Hash Table + Linked List |
---|---|---|---|---|---|
Set |
HashSet | TreeSet | LinkedHashSet | ||
List |
ArrayList | LinkedList | |||
Deque |
ArrayDeque | LinkedList | |||
Map |
HashMap | TreeMap | LinkedHashMap |
每个接口都有最常用的实现:HashSet, ArrayList, HashMap,而其他的实现使用频率都差不多。对于Queue来说有两个通用的实现,LinkedList和PriorityQueue 。
下面是接口和实现一起的图:
常用接口:
Queue:
First Element (Head) | Last Element (Tail) | |||
Throws exception | Special value | Throws exception | Special value | |
Insert | addFirst(e) |
offerFirst(e) |
addLast(e) |
offerLast(e) |
Remove | removeFirst() |
pollFirst() |
removeLast() |
pollLast() |
Examine | getFirst() |
peekFirst() |
getLast() |
peekLast() |
Queue通常,但并不必须是FIFO的,也有可能是LIFO(stack)的,不管怎样,remove的时候总是去掉头部
Deque:
First Element (Head) | Last Element (Tail) | |||
Throws exception | Special value | Throws exception | Special value | |
Insert | addFirst(e) |
offerFirst(e) |
addLast(e) |
offerLast(e) |
Remove | removeFirst() |
pollFirst() |
removeLast() |
pollLast() |
Examine | getFirst() |
peekFirst() |
getLast() |
peekLast() |
Queue Method |
Equivalent Deque Method |
add(e) |
addLast(e) |
offer(e) |
offerLast(e) |
remove() |
removeFirst() |
poll() |
pollFirst() |
element() |
getFirst() |
peek() |
peekFirst() |
Stack Method | Equivalent Deque Method |
push(e) |
addFirst(e) |
pop() |
removeFirst() |
peek() |
peekFirst() |
常用实现:
点击相应标题进入官方api文档
HashSet:
基本操作,如add, remove, contains 和 size等都是常数时间的。遍历做需要的时间是和HashSet的capacity加上里面的元素成正比的,所以capacity不要设置的太高(或者load factor不要太低)。
默认构造函数 HashSet() 会将capacity设置成16,load factor设置成0.75
或者也可以使用如下构造函数
HashSet(int initialCapacity)
HashSet(itn initialCapacity, float LoadFactor)
常用函数:
clear() void
ArrayList:
这个实现基本和Vector等价,只是ArrayList是线程不安全的,而Vector已经很古老了,基本不去用了。
size, isEmpty, get, set,几个是常数时间复杂度。add是amortized constant,其他的操作基本上都是线性的。
LinkedList:
这是一个双向链表,同时实现了List,Queue,Deque(Deque是Queue的sub-interface)。
因为是一个双向链表,所以既能够FIFO也能够LIFO
getFirst() E
getLast() E
removeFirst() E 删除并返回第一个
removeLast() E 删除并返回最后一个
offerFirst(E e) / offerLast(E e) void 插入
pollFirst() / pollLast() E 删除并返回,如果是空list,返回null
peekFirst() / peekLast() E 返回但不删除,如果是空list,返回null
Stack的方法:
push(E e) void push一个元素到stack中
pop() E 从stack中pop一个元素
PriorityQueue:
此实现是基于heap数据结构的,里面的元素按自然顺序排列,从小到大。heap的头部是最小的,
初始化时可以传入自定义的Comparator
PriorityQueue(Comparator<? super E> comparator)
常用函数:
poll() E 删除并返回这个heap的head,如果是空的则返回null
peek() E 返回但不删除这个heap的head,如果是空的则返回null
HashMap:
基本操作,如get 和 put 是常数时间的,和HashSet一样,遍历做需要的时间是和HashSet的capacity加上里面的元素(key-value mapping的个数)成正比的,所以capacity不要设置的太高(或者load factor不要太低)。
常用函数:
containsKey(Object key) boolean
containsValue(Object value) boolean
算法:
大部分的算法主要用在List上,少数一下可以用在任意的Collection上。
排序 Sorting:
按照自然顺序(小到大)将List排序,sort使用优化过的merge sort,保证了时间复杂度已经稳定性
时间复杂度:确保在 n log(n) 时间复杂度内
稳定(stable):保证同样大小的元素顺序保持一致
例子:
1 List<String> list = Arrays.asList(args); 2 Collections.sort(list); 3 System.out.println(list);
注意的是这里Collections是有s结尾的!
搜寻 Searching:
binarySearch
参考:
https://docs.oracle.com/javase/8/docs/technotes/guides/collections/overview.html
https://docs.oracle.com/javase/tutorial/collections/implementations/summary.html