java基礎-中級(一)【集合】
目錄
1.2.5 雙端佇列(ArrayDeque、LinkedList)
1、集合
定義:集合是用來存放物件的容器。
由來:當我們建立了很多物件並且想要使用,存放的位置可以使陣列,但是在並不知道數量的情況下,就出現了集合來存放物件
java集合解決的問題:當需要快速的搜尋成千上萬的資料項,需要快速的在有序的序列中間插入或刪除元素,建立鍵與值之間的關聯,這時候java集合類庫提供了大量的類和方法。
1.1 集合框架
Java的集合類庫構成了集合類的框架。它為集合的實現者定義了大量的介面和抽象類,見下圖(java集合框架圖)。
Java 集合框架主要包括兩種型別的容器,一種是集合(Collection),儲存一個元素集合,另一種是圖(Map),儲存鍵/值對對映。
1.1.1 集合介面
序號 | 介面描述 |
---|---|
1 | Collection 介面 Collection 是最基本的集合介面,一個 Collection 代表一組 Object,即 Collection 的元素, Java不提供直接繼承自Collection的類,只提供繼承於的子介面(如List和set)。 Collection 介面儲存一組不唯一,無序的物件。 |
2 | List 介面 List介面是一個有序的 Collection,使用此介面能夠精確的控制每個元素插入的位置,能夠通過索引(元素在List中位置,類似於陣列的下標)來訪問List中的元素,第一個元素的索引為 0,而且允許有相同的元素。 List 介面儲存一組不唯一,有序(插入順序)的物件。 |
3 | Set Set 具有與 Collection 完全一樣的介面,只是行為上不同,Set 不儲存重複的元素。 Set 介面儲存一組唯一,無序的物件。 |
4 | SortedSet 繼承於Set儲存有序的集合。 |
5 | Map Map 介面儲存一組鍵值物件,提供key(鍵)到value(值)的對映。 |
6 | Map.Entry 描述在一個Map中的一個元素(鍵/值對)。是一個Map的內部類。 |
7 | SortedMap 繼承於 Map,使 Key 保持在升序排列。 |
8 | Enumeration 這是一個傳統的介面和定義的方法,通過它可以列舉(一次獲得一個)物件集合中的元素。這個傳統介面已被迭代器取代。 |
1.1.2 集合實現類
序號 | 類描述 |
---|---|
1 | AbstractCollection 實現了大部分的集合介面。 |
2 | AbstractList 繼承於AbstractCollection 並且實現了大部分List介面。 |
3 | AbstractSequentialList 繼承於 AbstractList ,提供了對資料元素的鏈式訪問而不是隨機訪問。 |
4 | LinkedList 該類實現了List介面,允許有null(空)元素。主要用於建立連結串列資料結構,該類沒有同步方法,如果多個執行緒同時訪問一個List,則必須自己實現訪問同步,解決方法就是在建立List時候構造一個同步的List。例如: LinkedList 查詢效率低。 |
5 | ArrayList 該類也是實現了List的介面,實現了可變大小的陣列,隨機訪問和遍歷元素時,提供更好的效能。該類也是非同步的,在多執行緒的情況下不要使用。ArrayList 增長當前長度的50%,插入刪除效率低。 |
6 | AbstractSet 繼承於AbstractCollection 並且實現了大部分Set介面。 |
7 | HashSet 該類實現了Set介面,不允許出現重複元素,不保證集合中元素的順序,允許包含值為null的元素,但最多隻能一個。 |
8 | LinkedHashSet 具有可預知迭代順序的 Set 介面的雜湊表和連結列表實現。 |
9 | TreeSet 該類實現了Set介面,可以實現排序等功能。 |
10 | AbstractMap 實現了大部分的Map介面。 |
11 | HashMap HashMap 是一個散列表,它儲存的內容是鍵值對(key-value)對映。 該類實現了Map介面,根據鍵的HashCode值儲存資料,具有很快的訪問速度,最多允許一條記錄的鍵為null,不支援執行緒同步。 |
12 | TreeMap 繼承了AbstractMap,並且使用一顆樹。 |
13 | WeakHashMap 繼承AbstractMap類,使用弱金鑰的雜湊表。 |
14 | LinkedHashMap 繼承於HashMap,使用元素的自然順序對元素進行排序. |
15 | IdentityHashMap 繼承AbstractMap類,比較文件時使用引用相等。 |
1.1.3 迭代器
在集合中的基本介面都是Collection介面。這個介面有兩個基本方法:
public interface Colletion<E>{
boolean add(E element);
Iterator<E>iterator();
}
add的方法是向集合中新增元素,而iterator方法是返回一個Iterator迭代器,最終使用迭代器物件依次訪問集合中的元素。
迭代器Iterator的基本方法
返回 | 方法 |
---|---|
default void |
forEachRemaining(Consumer<? super E> action) 對每個剩餘元素執行給定的操作,直到所有元素都被處理或動作引發異常。 |
boolean |
hasNext() 如果迭代具有更多元素,則返回 |
E |
next() 返回迭代中的下一個元素。 |
default void |
remove() 從底層集合中刪除此迭代器返回的最後一個元素(可選操作)。 |
迭代器的使用:
Collection<String> collection = new ArrayList<String>();
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()){
String next = iterator.next();
//.......
}
java SE5之後開始使用for each用法,更加簡潔
Collection<String> collection = new ArrayList<String>();
for (String str:collection) {
//.........
}
1.2 具體的集合
集合按照底層型別進行劃分為:連結串列、陣列列表、雜湊集、樹集、佇列、對映表。
1.2.1 連結串列(LinkedList)
連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列的特點是:插入和刪除快,查詢慢。因為修改連結串列只需要將相鄰的指標進行改變,所以速度快;查詢需要遍歷所有的資料,所以較慢。
底層使用連結串列的常用集合為LinkedList。
LinkedList類結構
LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
LinkedList 是 Java 集合框架中一個重要的實現,其底層採用的雙向連結串列結構。和 ArrayList 一樣,LinkedList 也支援空值和重複值。LinkedList 是非執行緒安全的集合類,併發環境下,多個執行緒同時操作 LinkedList,會引發不可預知的錯誤。
LinkedList最大的好處在於頭尾和已知節點的插入和刪除時間複雜度都是o(1)。但是涉及到先確定位置再操作的情況,則時間複雜度會變為o(n)。
LinkedList的底層節點為一個Node,資訊都存放在物件中,Node類原始碼如下:(是一個內部類)
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
新增和刪除首尾的節點時,直接將節點改變指標即可,時間複雜度為o(1),如下所示:
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
LinkedList的add方法是常用的方法,如果add(E element)時,直接插入到連結串列的尾部即可,但是如果使用
add(index,E element)方法就會增加開銷,增大空間複雜度為o(n)。如下所示:
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
1.2.2 陣列列表(ArrayList)
陣列列表的實現類常用的為ArrayList,它的底層結構是陣列。它的特點是增刪慢,查詢快。注意:當想要使用vector時,因為vector時同步的,所以要多個執行緒訪問時才推薦使用vector。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
1.2.3 雜湊集(HashSet)
連結串列和陣列都可以按照意願來給元素排列順序,但是檢視某個指定的元素時,不知道它的位置的時候,要遍歷所有元素直到找到為止,將會消耗很多時間。
定義:一種資料結構,可以快速的訪問所需要的物件,這個就叫散列表。散列表給每個物件計算一個整數,稱之為雜湊碼(hash code)。hashSet是使用的雜湊集。
在java中,散列表是由連結串列和陣列構成,每個列表稱之為“桶”。查詢物件的方法就是:計算雜湊碼,與桶的總數取餘,找到儲存元素的桶的索引,再去找這個元素的位置。
雜湊衝突:當我們存放資料的時候,可能到某個桶時,桶已經滿了,這個叫做雜湊衝突。
唯一性:當使用add方法時,會檢查該物件是否已經存在,具體比較如下:
使用Set集合是要去除重複元素,如果在儲存的時候逐equals()比較,效率太低,雜湊演算法提高了去重複的效率,減少了使用equals()方法的次數,當HashSet物件呼叫add()方法儲存物件時,會呼叫物件的HashCode()方法得到一個雜湊值,然後在集合中查詢是否有雜湊值相同的物件,如果用,則呼叫equals()方法比較,如果沒有則直接存入集合。
因此,如果自定義類物件存入集合去重複,需要重寫equals()方法和HashCode()方法。
1.2.4 樹集(TreeSet)
TreeSet類與雜湊集有些相似。樹集是一個有序的集合,元素插入到集合後,遍歷集合將是有序的元素。這種排序用的是一種演算法:紅黑樹。(具體的紅黑樹後面學習)
紅黑樹規則:
1、每個結點都只能是紅色或者黑色中的一種。
2、根結點是黑色的。
3、每個葉結點(NIL節點,空節點)是黑色的。
4、如果一個結點是紅的,則它兩個子節點都是黑的。也就是說在一條路徑上不能出現相鄰的兩個紅色結點。
5、從任一結點到其每個葉子的所有路徑都包含相同數目的黑色結點。
將元素新增到樹中的速度要比散列表慢,但是唯一的特點就是可以排序,但是比連結串列和陣列要快。物件的比較使用的是介面Comparable,所以要使用TreeSet的排序,物件要實現介面Comparable。
1.2.5 雙端佇列(ArrayDeque、LinkedList)
佇列可以在頭部刪除、尾部增加,但是雙端佇列是可以在頭部和尾部增加和刪除,主要是實現的Deque介面。Deque 介面繼承自 Queue介面,但 Deque 支援同時從兩端新增或移除元素,因此又被成為雙端佇列。
1.2.6 對映表(HashMap、TreeMap)
對映表是存放鍵值對的形式來存在的。Java類庫中提供了兩個實現類:HashMap、TreeMap,兩個類都實現了Map介面。
HashMap的鍵是由散列表來構成,TreeMap的鍵是由樹的結構來形成。
在對映表中,鍵是唯一的,不能在同一個鍵中存放兩個值。
1.3 常用方法
1.3.1 Collection的常用方法
返回值 | 方法名稱 |
---|---|
boolean |
add(E e) 確保此集合包含指定的元素(可選操作)。 |
boolean |
addAll(Collection<? extends E> c) 將指定集合中的所有元素新增到此集合(可選操作)。 |
void |
clear() 從此集合中刪除所有元素(可選操作)。 |
boolean |
contains(Object o) 如果此集合包含指定的元素,則返回 true 。 |
boolean |
containsAll(Collection<?> c) 如果此集合包含指定 集合中的所有元素,則返回true。 |
boolean |
equals(Object o) 將指定的物件與此集合進行比較以獲得相等性。 |
int |
hashCode() 返回此集合的雜湊碼值。 |
boolean |
isEmpty() 如果此集合不包含元素,則返回 true 。 |
Iterator<E> |
iterator() 返回此集合中的元素的迭代器。 |
default Stream<E> |
parallelStream() 返回可能並行的 |
boolean |
remove(Object o) 從該集合中刪除指定元素的單個例項(如果存在)(可選操作)。 |
boolean |
removeAll(Collection<?> c) 刪除指定集合中包含的所有此集合的元素(可選操作)。 |
default boolean |
removeIf(Predicate<? super E> filter) 刪除滿足給定謂詞的此集合的所有元素。 |
boolean |
retainAll(Collection<?> c) 僅保留此集合中包含在指定集合中的元素(可選操作)。 |
int |
size() 返回此集合中的元素數。 |
default Spliterator<E> |
spliterator() 建立一個 |
default Stream<E> |
stream() 返回以此集合作為源的順序 |
Object[] |
toArray() 返回一個包含此集合中所有元素的陣列。 |
<T> T[] |
toArray(T[] a) 返回包含此集合中所有元素的陣列; 返回的陣列的執行時型別是指定陣列的執行時型別。 |
1.3.2 Map的常用方法
返回值 | 方法名 |
---|---|
void |
clear() 從該Map刪除所有的對映(可選操作)。 |
default V |
compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 嘗試計算指定鍵的對映及其當前對映的值(如果沒有當前對映, |
default V |
computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) 如果指定的鍵尚未與值相關聯(或對映到 |
default V |
computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 如果指定的金鑰的值存在且非空,則嘗試計算給定金鑰及其當前對映值的新對映。 |
boolean |
containsKey(Object key) 如果此對映包含指定鍵的對映,則返回 true 。 |
boolean |
containsValue(Object value) 如果此Map將一個或多個鍵對映到指定的值,則返回 true 。 |
Set<Map.Entry<K,V>> |
entrySet() 返回此Map中包含的對映的 |
boolean |
equals(Object o) 將指定的物件與此對映進行比較以獲得相等性。 |
default void |
forEach(BiConsumer<? super K,? super V> action) 對此對映中的每個條目執行給定的操作,直到所有條目都被處理或操作引發異常。 |
V |
get(Object key) 返回到指定鍵所對映的值,或 |
default V |
getOrDefault(Object key, V defaultValue) 返回到指定鍵所對映的值,或 |
int |
hashCode() 返回此Map的雜湊碼值。 |
boolean |
isEmpty() 如果此地圖不包含鍵值對映,則返回 true 。 |
Set<K> |
keySet() 返回此地圖中包含的鍵的 |
default V |
merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) 如果指定的鍵尚未與值相關聯或與null相關聯,則將其與給定的非空值相關聯。 |
V |
put(K key, V value) 將指定的值與該對映中的指定鍵相關聯(可選操作)。 |
void |
putAll(Map<? extends K,? extends V> m) 將指定地圖的所有映射覆制到此對映(可選操作)。 |
default V |
putIfAbsent(K key, V value) 如果指定的鍵尚未與某個值相關聯(或對映到 |
V |
remove(Object key) 如果存在(從可選的操作),從該地圖中刪除一個鍵的對映。 |
default boolean |
remove(Object key, Object value) 僅當指定的金鑰當前對映到指定的值時刪除該條目。 |
default V |
replace(K key, V value) 只有當目標對映到某個值時,才能替換指定鍵的條目。 |
default boolean |
replace(K key, V oldValue, V newValue) 僅噹噹前對映到指定的值時,才能替換指定鍵的條目。 |
default void |
replaceAll(BiFunction<? super K,? super V,? extends V> function) 將每個條目的值替換為對該條目呼叫給定函式的結果,直到所有條目都被處理或該函式丟擲異常。 |
int |
size() 返回此地圖中鍵值對映的數量。 |
Collection<V> |
values() 返回此地圖中包含的值的 |
1.3.3 工具類Collections的常用方法
-
此類僅由靜態方法組合或返回集合。 它包含對集合進行操作的多型演算法,“包裝器”,返回由指定集合支援的新集合,以及其他一些可能的和最終的。
返回值 | 方法名稱 |
---|---|
static <T> boolean |
addAll(Collection<? super T> c, T... elements) 將所有指定的元素新增到指定的集合。 |
static <T> Queue<T> |
asLifoQueue(Deque<T> deque) |
static <T> int |
binarySearch(List<? extends Comparable<? super T>> list, T key) 使用二叉搜尋演算法搜尋指定物件的指定列表。 |
static <T> int |
binarySearch(List<? extends T> list, T key, Comparator<? super T> c) 使用二叉搜尋演算法搜尋指定物件的指定列表。 |
static <E> Collection<E> |
checkedCollection(Collection<E> c, 類<E> type) 返回指定集合的動態型別安全檢視。 |
static <E> List<E> |
checkedList(List<E> list, 類<E> type) 返回指定列表的動態型別安全檢視。 |
static <K,V> Map<K,V> |
checkedMap(Map<K,V> m, 類<K> keyType, 類<V> valueType) 返回指定地圖的動態型別安全檢視。 |
static <K,V> NavigableMap<K,V> |
checkedNavigableMap(NavigableMap<K,V> m, 類<K> keyType, 類<V> valueType) 返回指定可導航地圖的動態型別安全檢視。 |
static <E> NavigableSet<E> |
checkedNavigableSet(NavigableSet<E> s, 類<E> type) 返回指定的可導航集的動態型別安全檢視。 |
static <E> Queue<E> |
checkedQueue(Queue<E> queue, 類<E> type) 返回指定佇列的動態型別安全檢視。 |
static <E> Set<E> |
checkedSet(Set<E> s, 類<E> type) 返回指定集合的動態型別安全檢視。 |
static <K,V> SortedMap<K,V> |
checkedSortedMap(SortedMap<K,V> m, 類<K> keyType, 類<V> valueType) 返回指定排序對映的動態型別安全檢視。 |
static <E> SortedSet<E> |
checkedSortedSet(SortedSet<E> s, 類<E> type) 返回指定排序集的動態型別安全檢視。 |
static <T> void |
copy(List<? super T> dest, List<? extends T> src) 將所有元素從一個列表複製到另一個列表中。 |
static boolean |
disjoint(Collection<?> c1, Collection<?> c2) 如果兩個指定的集合沒有共同的元素,則返回 |
static <T> Enumeration<T> |
emptyEnumeration() 返回沒有元素的列舉。 |
static <T> Iterator<T> |
emptyIterator() 返回沒有元素的迭代器。 |
static <T> List<T> |
emptyList() 返回空列表(immutable)。 |
static <T> ListIterator<T> |
emptyListIterator() 返回沒有元素的列表迭代器。 |
static <K,V> Map<K,V> |
emptyMap() 返回空的地圖(不可變)。 |
static <K,V> NavigableMap<K,V> |
emptyNavigableMap() 返回空導航地圖(不可變)。 |
static <E> NavigableSet<E> |
emptyNavigableSet() 返回一個空導航集(immutable)。 |
static <T> Set<T> |
emptySet() 返回一個空集(immutable)。 |
static <K,V> SortedMap<K,V> |
emptySortedMap() 返回空的排序對映(immutable)。 |
static <E> SortedSet<E> |
emptySortedSet() 返回一個空的排序集(immutable)。 |
static <T> Enumeration<T> |
enumeration(Collection<T> c) 返回指定集合的列舉。 |
static <T> void |
fill(List<? super T> list, T obj) 用指定的元素代替指定列表的所有元素。 |
static int |
frequency(Collection<?> c, Object o) 返回指定集合中與指定物件相等的元素數。 |
static int |
indexOfSubList(List<?> source, List<?> target) 返回指定源列表中指定目標列表的第一次出現的起始位置,如果沒有此類事件,則返回-1。 |
static int |
lastIndexOfSubList(List<?> source, List<?> target) 返回指定源列表中指定目標列表的最後一次出現的起始位置,如果沒有此類事件則返回-1。 |
static <T> ArrayList<T> |
list(Enumeration<T> e) 返回一個數組列表,其中包含由列舉返回的順序由指定的列舉返回的元素。 |
static <T extends Object & Comparable<? super T>> |
max(Collection<? extends T> coll) 根據其元素的 自然順序返回給定集合的最大元素。 |
static <T> T |
max(Collection<? extends T> coll, Comparator<? super T> comp) 根據指定的比較器引發的順序返回給定集合的最大元素。 |
static <T extends Object & Comparable<? super T>> |
min(Collection<? extends T> coll) 根據其元素的 自然順序返回給定集合的最小元素。 |
static <T> T |
min(Collection<? extends T> coll, Comparator<? super T> comp) 根據指定的比較器引發的順序返回給定集合的最小元素。 |
static <T> List<T> |
nCopies(int n, T o) 返回由指定物件的 n副本組成的不可變列表。 |
static <E> Set<E> |
newSetFromMap(Map<E,Boolean> map) 返回由指定地圖支援的集合。 |
static <T> boolean |
replaceAll(List<T> list, T oldVal, T newVal) 將列表中一個指定值的所有出現替換為另一個。 |
static void |
reverse(List<?> list) 反轉指定列表中元素的順序。 |
static <T> Comparator<T> |
reverseOrder() 返回一個比較器,它對實現 |
static <T> Comparator<T> |
reverseOrder(Comparator<T> cmp) 返回一個比較器,它強制指定比較器的反向排序。 |
static void |
rotate(List<?> list, int distance) 將指定列表中的元素旋轉指定的距離。 |
static void |
shuffle(List<?> list) 使用預設的隨機源隨機排列指定的列表。 |
static void |
shuffle(List<?> list, Random rnd) 使用指定的隨機源隨機排列指定的列表。 |
static <T> Set<T> |
singleton(T o) 返回一個只包含指定物件的不可變集。 |
static <T> List<T> |
singletonList(T o) 返回一個只包含指定物件的不可變列表。 |
static <K,V> Map<K,V> |
singletonMap(K key, V value) 返回一個不可變的地圖,只將指定的鍵對映到指定的值。 |
static <T extends Comparable<? super T>> |
sort(List<T> list) 根據其元素的natural ordering對指定的列表進行排序。 |
static <T> void |
sort(List<T> list, Comparator<? super T> c) 根據指定的比較器引起的順序對指定的列表進行排序。 |
static void |
swap(List<?> list, int i, int j) 交換指定列表中指定位置的元素。 |
static <T> Collection<T> |
synchronizedCollection(Collection<T> c) 返回由指定集合支援的同步(執行緒安全)集合。 |
static <T> List<T> |
synchronizedList(List<T> list) 返回由指定列表支援的同步(執行緒安全)列表。 |
static <K,V> Map<K,V> |
synchronizedMap(Map<K,V> m) 返回由指定地圖支援的同步(執行緒安全)對映。 |
static <K,V> NavigableMap<K,V> |
synchronizedNavigableMap(NavigableMap<K,V> m) 返回由指定的可導航地圖支援的同步(執行緒安全)可導航地圖。 |
static <T> NavigableSet
|