常用集合之間的關系:
1:list的子類 :list集合包含重復元素,並且有序(存儲順序和取出順序一致);
ArrayList: 底層是數組,線程不安全,查詢快,增刪慢,效率高;
vector: 底層是數組,線程安全,查詢快,增刪慢,效率低;
linkedList: 底層是鏈表,線程不安全,查詢慢,增刪快,效率高;
2:set類集合: set集合不包含重復,具有唯一性;
HashSet: 唯一性;
LinkedHashSet : 底層是hash表(唯一性)和鏈表(存放和取出有序)組成,所以具有唯一性和有序性;
TreeSet : 唯一性,集合內部有兩種排序方式:自然排序 和 比較器排序;
3: Map類集合: 鍵值對集合,鍵具有唯一性;
HashMap: 存儲無序,鍵具有唯一性;
TreeMap: 存儲為自然排序,鍵具有唯一性;
LinkedHashMap: 存放和取出有序,鍵具有唯一性;
Queue
隊列集合在集合的基礎上添加了增刪改查操作,並且隊列默認使用FIFO(先進先出)規則。
Queue接口:
隊列的主要特點是在基本的集合方法之外,還提供特殊的插入、獲取和檢驗操作。每個操作都提供兩個方法,一種返回異常,一種返回null或者false.
隊列一般滿足先進先出規則(FIFO),除了優先隊列(priority queue)和棧(stack),但是棧是FILO(先進后出規則),優先隊列自己定義了排序規則。
隊列不允許插入null元素,但是LinkedList可以
- add(E e) 插入一個元素到隊列中,失敗時返回IllegalStateException (隊列容量不夠)
- element() 返回隊列頭部的元素
- peek() 返回隊列頭部的元素,隊列為空時返回null
- offer(E e) 插入一個元素到隊列中,失敗時返回false
- poll() 返回並移除隊列的頭部元素,隊列為空時返回null
- remove() 返回並移除隊列的頭部元素,為空時報錯
Deque
雙端隊列是一種線性集合,可以從兩端操作的隊列。
Deque的抽象數據模型
ADT Deque Data 數據集合為{a1,a2,a3...an},數據類型都是DataType,雙端隊列,可以同時在隊列的兩端進行插入和獲取操作。 Operations InitDeque(); 初始化一個空隊列 PeekFirstDeque(); 獲取隊列的頭部元素 PeekLastDeque(); 獲取隊列的尾部元素 ClearDeque(); 清空隊列的元素 DequeEmpty(); 判斷隊列是否為空 OfferFirstDeque(DataType d); 將元素d添加到隊列頭部 OfferFirstDeque(DataType d); 將元素d添加到隊列尾部 DequeLength(); 隊列的長度
Deque接口
雙端隊列
- add(E e) 將新元素添加到隊列的尾端(當不超過隊列的容量時)
- addFirst(E e) 將新元素添加到隊列的頭部
- addLast(E e) 將新元素添加到隊列的尾部
- contains(Object o) 雙端隊列是否含有對象o
- descendingIterator()倒敘返回隊列的迭代器
- element() 返回隊列的頭部元素
- getFirst() 獲取頭部元素
- getLast() 獲取尾部元素
- iterator() 迭代隊列
- offer(E e) 將新元素插入到隊列尾部
- offerFirst(E e) 將新元素添加到隊列的頭部
- offerLast(E e) 將新元素添加到隊列的尾部
- peek() 返回隊列的頭部元素
- peekFirst() 獲取頭部元素
- peekLast() 獲取尾部元素
- pool() 返回並移除隊列的頭部元素
- poolFirst() 獲取並移除頭部元素
- poolLast() 獲取並移除尾部元素
- pop() 將一個元素出棧
- push(E e) 講一個元素壓入棧
- remove() 移除隊列的頭部元素
- remove(Object o) 移除隊列中第一個o
- removeFirst() 移除隊列的頭部元素
- removeFirstOccurrence(Object o) 移除隊列中第一個o
- removeLast() 移除隊列的尾部元素
- removeLastOccurrence(Object o) 移除隊列中最后一個o
- size()
ArrayDeque
雙端隊列的數組實現類,底層數據存儲在數組中,數組雙端隊列是可擴容的.
數組雙端隊列就是雙端隊列接口的實現類,沒有額外的功能,這里不詳細討論了。
PriorityQueue
不同於Queue,PriorityQueue優先隊列默認按照自然順序排序元素,或者按照定義的比較器排序元素。
邏輯上使用堆結構(完全二叉樹)實現,物理上使用動態數組實現,並非像TreeMap一樣完全有序,但是如果按照指定方式出隊,結果可以是有序的。
可參考:堆結構的優秀實現類----PriorityQueue優先隊列
BlockingQueue
A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
BlockingQueue methods come in four forms, with different ways of handling operations that cannot be satisfied immediately, but may be satisfied at some point in the future: one throws an exception, the second returns a special value (either null or false, depending on the operation), the third blocks the current thread indefinitely until the operation can succeed, and the fourth blocks for only a given maximum time limit before giving up.
阻塞隊列用於處理當前操作無法立即滿足的場景,比如隊列中沒有多余的存儲空間時。
阻塞隊列有四種實現方式:第一種當目前操作無法滿足時,立即拋出異常,第二種當目前操作無法滿足時,返回null或者false,第三種會無限阻塞直到操作成功,第四種會阻塞一定的時間(given maximum time limit)直到操作成功或者到時間期限后放棄。
BlockingQueue繼承了Queue接口,具有隊列的特性,同時定義了阻塞方法的通用實現。
void put(E e) 將特定元素插入阻塞隊列,如果當前隊列空間不夠則等待知道隊列有足夠的存儲空間
boolean offer(E e, long timeout, TimeUnit unit) 將特定元素插入阻塞隊列,如果當前隊列空間不夠則等待知道隊列有足夠的存儲空間,或者等待時間達到timeout后放棄操作
E take() 查找並且移除隊列的頭部元素,或者等待知道隊列中有元素
E poll(long timeout, TimeUnit unit) 查找並且移除隊列的頭部元素,或者等待知道隊列中有元素,或者等待時間達到timeout后放棄操作
int drainTo(Collection< ? super E> c) 將隊列中的元素全部刪除並且添加到集合c,如果發生異常,可能會出現一個元素同時存在隊列和集合c的情況
int drainTo(Collection< ? super E> c, int maxElements) 將隊列中的元素刪除並且添加到集合c,最多不超過maxElements,如果發生異常,可能會出現一個元素同時存在隊列和集合c的情況
BlockingQueue的實現類可以參考:Java多線程15:Queue、BlockingQueue以及利用BlockingQueue實現生產者/消費者模型
面試相關:
1:HashMap與Hashtable的區別:
HashMap: 線程不安全,允許null鍵和null值;
Hashtable: 線程安全,不允許null鍵和null值;
2:list、set、Map是否都是繼承map ??
否,list、set繼承的collection接口,而map接口本身就是一個頂層接口;
3:collection與collections的區別:
collection : 是單列集合的頂層接口,有子接口list、set;
collections: 是針對集合操作的工具類,像常用的:對集合進行排序和二分查找;
collections的常用方法:
collections里面都是靜態方法:
collections.sort(List<> list) :集合的自然排序;
collections.binarySearch(List<> list ,T key) : 集合的二分查找;
collections.max() : 獲取最大值;
collections .reverse() : 元素反轉;
collections .shuffle() : 元素位置隨機置換;
4:開發中如何使用線程安全的集合?
List<Object> objects = Collections.synchronizedList(new ArrayList<>());