1. 程式人生 > >java基礎-中級(一)【集合】

java基礎-中級(一)【集合】

目錄

 

1、集合

1.1 集合框架

         1.1.1 集合介面

         1.1.2 集合實現類

         1.1.3 迭代器

1.2 具體的集合

         1.2.1 連結串列(LinkedList)

         1.2.2 陣列列表(ArrayList)

         1.2.3 雜湊集(HashSet)

         1.2.4 樹集(TreeSet)

         1.2.5 雙端佇列(ArrayDeque、LinkedList)

         1.2.6 對映表(HashMap、TreeMap)

1.3 常用方法

          1.3.1 Collection的常用方法

          1.3.2 Map的常用方法

          1.3.3 工具類Collections的常用方法


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。例如:

Listlist=Collections.synchronizedList(newLinkedList(...));

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()

如果迭代具有更多元素,則返回 true

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()

返回可能並行的 Stream與此集合作為其來源。

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()

建立一個Spliterator在這個集合中的元素。

default Stream<E> stream()

返回以此集合作為源的順序 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)

嘗試計算指定鍵的對映及其當前對映的值(如果沒有當前對映, null )。

default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

如果指定的鍵尚未與值相關聯(或對映到 null ),則嘗試使用給定的對映函式計算其值,並將其輸入到此對映中,除非 null

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中包含的對映的Set檢視。

boolean equals(Object o)

將指定的物件與此對映進行比較以獲得相等性。

default void forEach(BiConsumer<? super K,? super V> action)

對此對映中的每個條目執行給定的操作,直到所有條目都被處理或操作引發異常。

V get(Object key)

返回到指定鍵所對映的值,或 null如果此對映包含該鍵的對映。

default V getOrDefault(Object key, V defaultValue)

返回到指定鍵所對映的值,或 defaultValue如果此對映包含該鍵的對映。

int hashCode()

返回此Map的雜湊碼值。

boolean isEmpty()

如果此地圖不包含鍵值對映,則返回 true 。

Set<K> keySet()

返回此地圖中包含的鍵的Set檢視。

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)

如果指定的鍵尚未與某個值相關聯(或對映到 null )將其與給定值相關聯並返回 null ,否則返回當前值。

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()

返回此地圖中包含的值的Collection檢視。

1.3.3 工具類Collections的常用方法

  • 此類僅由靜態方法組合或返回集合。 它包含對集合進行操作的多型演算法,“包裝器”,返回由指定集合支援的新集合,以及其他一些可能的和最終的。

返回值 方法名稱
static <T> boolean addAll(Collection<? super T> c, T... elements)

將所有指定的元素新增到指定的集合。

static <T> Queue<T> asLifoQueue(Deque<T> deque)

返回Deque作為先進先出( LifoQueue的檢視

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)

如果兩個指定的集合沒有共同的元素,則返回 true

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>>
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>>
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()

返回一個比較器,它對實現 Comparable介面的物件集合施加了 自然排序的相反。

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>>
void
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