Java Collections
Collections Framework Overview
Overview
Interface
List
ArrayList
Stack
(Not Recommended)LinkedList
Queue
LinkedList
ArrayDeque
PriorityQueue
Deque
(inherited fromQueue
)LinkedList
ArrayDeque
List vs. Queue
- List有index概念,支持随机访问
- Queue没有index概念
- java的Stack被淘汰了,因为性能不够好。
Interface - List
API
size()
isEmpty()
- Random Access
set(int index, E e)
E get(int index)
add(int index, E e)
add(E e)
remove(int index)
remove(E e)
- Search
- Iterator
- Range-View
Class - ArrayList
- inital capacity 10 and expand by 1.5 times when there is no unused cells available
- size =
ArrayList.size()
- capacity =
ArrayList.length
当前内存容量 - 在删除很多元素后,容量减少到一定程度之后,ArrayList不会主动trimToSize,一般需要人工调用该方法。
Create an ArrayList from an Array
Initialization of an arraylist in one line
how to convert int[] into list
Interface - Queue & Deque
- Queue is a FIFO queue. (exception PriorityQueue)
- Deque is short for double-ended queue. Deque is FIFO & LIFO. (both queue and stack)
- Java里面实现Stack最好的接口是Deque,用LinkedList实现,不能用List,更不能直接用LinkedList。
API
Queue
offer(E e)
- offer at the tailE poll()
- poll at the headE peek()
- look at the head without polling it out
Deque
offerFirst(E e)
offerLast(E e)
=offer(E e)
addFirst(E e)
=push(E e)
E pollFirst()
=E poll()
E pollLast()
E removeFirst()
=E pop()
E peekFirst()
=E peek()
E peekLast()
Locations-------First-----------------Last
Operations-----add/push---------------offer
--------------remove/pop------------------
----------------poll----------------------
Operations of Queue and Stack
Operations | Queue | Stack |
---|---|---|
Insert | offer /add |
push /add |
Remove | poll /remove |
pop /remove |
Examine | peek /element |
peek /element |
Note:
add
,remove
andget
throw exception if error happensoffer
,poll
andpeek
return special value if error happens
Class - LinkedList & ArrayDeque
- Most popular implementation class:
LinkedList
,ArrayDeque
. ArrayDeque
is a newer implementation by circular array forDeque
. No null values in Deque.- For a queue or stack, we can just use
LinkedList
, as it implements bothQueue
andDeque
interfaces. - Java的LinkedList是Doubly Linked List,存有Head/Tail
Circular Array
- use varible
head
to record the index of the node before the head. - use varible
tail
to record the index of the node after the tail. - can store
n-1
elements with n-length array.
Class - ArrayList vs. LinkedList
How do we choose ArrayList or LinkedList?
- if there are very many random access, use ArrayList.
- always add/remove at the end, use ArrayList.
- If time complexity is similar for both, use ArrayList. Because LinkedList is memory-cost.
- Queue/Stack -> LinkedList
- Stack & Vector现在不用了,这两个是线程安全的,但是额外消耗了很多开销。 Stack->use LinkedList(ArrayDeque) Vector->use ArrayList
Class - PriorityQueue
- It implements the queue interface but it is not a FIFO queue. It is actually a min heap.
- It arranges the order of the elements by comparing any pair of elements.
- Time Complexity of size n
PriorityQueue
offer(E e)
-peek()
-poll()
-remove()
- - should not be usedsize()
-isEmpty()
-private heapify()
-
- heapify - use one
Collection
as initial argument - Order of the elements
- It is defaulted by returning -1 if x1 < x2;
- be CAREFUL not to return an overflowed value.
Comparator.compare(E o1, E o2)
provided when newing a PriorityQueue- needs not to change the original class
Comparable.compareTo(E another)
interface in class- use
Collections.reverseOrder()
- use
Collections.reverseOrder(new myComparator)
Possible ways to provide a comparator class
- top-level class (recommended)
- Static nested class
- Anonymous class (not recommended)
Lambda expressions (since Java 8)
class Cell implements Comparable<Cell>{ public int row; public int col; public int value; public Cell(int row, int col, value){ this.row = row; this.cell = cell; this.value = value; } @Override public int compareTo(Cell another){ if (this.value == another.value){ return 0; } return this.value < another.value ? -1:1; } } // will use compareTo() in the class PriorityQueue<Cell> minHeap = new PriorityQueue<Cell>(11); //interface Comparator<E>{ // int compare(E o1, E o2); //} class MyComparator implements Comparator<Cell>{ @Override public int compare(Cell c1, Cell c2){ if (c1.value == c2.value){ return 0; } // !IMPORTANT needs to return -1 or 1, or it might over MAX_INT. return c1.value - c2.value ? -1:1; } } // will use compare() in the provided Comparator PriorityQueue<Cell> minHeap = new PriorityQueue<Cell>(11, Collections.reverseOrder()); // self-defined comparator class PriorityQueue<Cell> minHeap = new PriorityQueue<Cell>(11, new MyComparator()); // anonymous comparator class PriorityQueue<Cell> minHeap = new PriorityQueue<Cell>(11, new Comparator<Cell>(){ public int compare(Integer one, Integer two){ return 0; } }); // lambda PriorityQueue<Cell> minHeap = new PriorityQueue<Cell>(11, (lhs, rhs) ->{ return 0; } );
Heap Implementation
percolateUp(int index)
- when need to move up one element
- eg. offering a new element into the heap.
offer()
- usepercolateUp
percolateDown(int index)
- when need to poll the root element from the heap.
poll()
- usepercolateDown
heapify()
- convert an array into a heap in time.
- perform
percolateDown
action in the order of from the nodes on the deepest level to the root. Only needs to do for the first half of the array. range:- No need to know how to prove
- if we perform
offer()
andpercolateUp
, the time complexity becomes
update()
- find the element in
- use either
percolateUp
orpercolateDown