Java---不知道用哪個集合?史上最全面的集合框架讓你分清各個集合的區別,小白也能懂

集合框架

在這裏插入圖片描述

單列集合

Collection(接口)

  特點: 部分集合有序,部分集合無序,部分集合唯一,部分集合可重複
   常用方法:
     添加
       boolean add(E e) 將指定的元素添加到此列表的尾部。
       boolean addAll(Collection<? extends E> c)
       將指定 collection 中的所有元素都添加到此 collection 中

     刪除
       void clear() 移除此 collection 中的所有元素(可選操作)。
      boolean remove(Object o) 從此 collection 中移除指定元素的單個實例
       boolean removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。

     修改 【無】

     遍歷
       Object[] toArray() 將集合轉換成數組
       注意: 數組轉換成集合: Arrays.asList(T… a);
       T[] toArray(T[] a) 泛型方法,將集合轉換成數組
       Iterator iterator() 返回在此 collection 的元素上進行迭代的迭代器。
       任何一個Collection的子類都可以使用迭代器遍歷

     判斷
       boolean contains(Object o) 判斷集合中是否包含某個元素o
       boolean containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,則返回 true。
       boolean isEmpty() 如果此 collection 不包含元素,則返回 true。

     其他
       boolean retainAll(Collection<?> c) 求交集
       int size() 獲取集合的長度
   遍歷方式:
     1.普通toArray
     2.泛型toArray
     3.迭代器Iterator
     4.foreach遍歷

List

  特點: 有序,可重複
   方法:
     添加
       void add(int index, E element)
         在列表的指定位置插入指定元素(可選操作)。
       boolean addAll(int index, Collection<? extends E> c)
        將指定 collection 中的所有元素都插入到列表中的指定位置(可選操作)。

     刪除
       E remove(int index)
         移除列表中指定位置的元素(可選操作)。

     修改
       E set(int index, E element)
         用指定元素替換列表中指定位置的元素(可選操作)。

    遍歷
       E get(int index)
       ListIterator listIterator()
         返回此列表元素的列表迭代器(按適當順序)。
       ListIterator listIterator(int index)
         返回列表中元素的列表迭代器(按適當順序),從列表的指定位置開始。

     獲取
       int indexOf(Object o) 返回此列表中第一次出現的指定元素的索引;如果此列表不包含該元素,則返回 -1。
       int lastIndexOf(Object o)
         返回此列表中最後出現的指定元素的索引;如果列表不包含此元素,則返回 -1。
       List subList(int fromIndex, int toIndex)
         返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的部分視圖。

   遍歷方式:
     5.普通for list.size() + list.get(int index)
     6.列表迭代器
       a.正向遍歷
       b.逆向遍歷
       c.從指定位置開始正向或者逆向遍歷

ArrayList

  特點:
   1. 底層數據結構是數組
   2. 增加和刪除的效率低,查詢和修改的效率高
   3. 能夠存儲 null 值
   4. 線程不安全,效率高 可以通過 Collections.synchronizedList();變安全
   5. 有索引,能夠方便檢索
   6. 元素可重複,我們自己可以通過
   去除重複元素
      a.創建一個新的集合,地址傳遞
      b.選擇排序思想去除重複元
      c.利用LinkedHashSet的構造器
   7. 不可以排序,但是可以通過 Collections.sort();方法排序
   8. 動態擴容原理
核心源碼解析
      private void grow(int minCapacity) {
         // overflow-conscious code
        int oldCapacity = elementData.length; // 0
        int newCapacity = oldCapacity + (oldCapacity / 2); // 擴容係數
        // ==> (1 + 1/2) * oldCapcity == > 1.5 * oldCapcity
         if (newCapacity < minCapacity)
         newCapacity = minCapacity; // 10
         if (newCapacity > MAX_ARRAY_SIZE)
        newCapacity = hugeCapacity(minCapacity);
         // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
      }
      a.擴容係數1.5倍
      b.如果超過int類型的範圍,拋出錯誤
      c.底層依賴的是Arrays.copyOf()方法,還是利用new或者反射創建了新的數組,copyOf方法底層依賴System.arraycopy方法

  常用方法: 來自於Collection和List接口

Vector

特點:和ArrayList完全兼容,但是它是線程安全,效率低,就算安全我們也不用,過時了
   常用方法:
     增加
       public synchronized void addElement(E obj) 添加元素 obj 到集合中
       public synchronized void insertElementAt(E obj, int index) 在指定索引 index 處插入元素 obj

     刪除
       public synchronized void removeElementAt(int index) 移除指定索引 index 處的元素
       public synchronized void removeAllElements() 移除所有元素

     修改
       public synchronized void setElementAt(E obj, int index) 修改指定索引 index 的元素爲 obj

    遍歷
         public synchronized ElementAt(int index) + size() for循環遍歷集合中的所有元素
       public synchronized Enumeration elements() 使用 Enumeration 迭代器遍歷集合中的元素

    獲取
       public synchronized E firstElement() 獲取集合中的第一個元素
       public synchronized E lastElement() 獲取集合中的最後一個元素
       public synchronized E elementAt(int index) 獲取指定索引 index 的元素

    遍歷方式:
       7. 普通for的老版本形式 ElementAt(int index) + size()
       8. 舊版迭代器Enumeration Enumeration elements()

ArrayList和Vector的區別?
    1) Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,由於線程的同步必然要影響性能,因此,ArrayList的性能比Vector好。

     2) 當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增加50%的大小,這樣,ArrayList就有利於節約內存空間。

Stack

  特點: 是Vector的子類,也過時了,同時具備棧結構的特點 【先進後出】
     可以考慮使用LinkedList

  常用方法:
     E push(E item) 將元素壓入棧底
     E pop() 將元素從棧結構中彈出,並作爲此函數的值返回該對象,此方法會影響棧結構的大小
     E peek() 查看堆棧頂部的對象,但不從棧中移除它。
     boolean empty() 測試棧是否爲空。
     int search(Object o) 返回對象在棧中的位置,以 1 爲基數。

  遍歷方式:
     棧結構的先進後出遍歷方式
         Stack stack = new Stack<>();
         // 壓棧
         stack.push(“A”);
         stack.push(“B”);
         stack.push(“C”);

        while (!stack.isEmpty()) {
         System.out.println(“棧頂元素:” + stack.peek());
         // 彈棧
         System.out.println(“彈出棧頂元素:” + stack.pop());
         }

LinkedList

  和ArrayList一樣可以通用
  但是它的底層數據結構是鏈表

Queue

  特點: 隊列數據結構相關的集合 【先進先出】
      1. 該接口是隊列接口的根接口,先進先出
      2. 該接口提供隊列相關兩種形式的方法,一種拋出異常(操作失敗時),另一種返回一個特殊值(nullfalse,具體取決於操作)。插入操作的後一種形式是用於專門爲有容量限制的 Queue 實現設計的;在大多數實現中,插入操作不會失敗。

   常用方法:
      拋出異常 返回特殊值
   插入 add(e) offer(e)
   移除 remove() poll()
   檢查 element() peek()

   遍歷方式:
      10.隊列結構遍歷方式
      Queue queue = new ArrayDeque<>();
      queue.add(“A”);
      queue.add(“B”);
      queue.add(“C”);

     while (!queue.isEmpty()) {
         System.out.println(queue.remove());
      }
      // 或者
      queue.offer(“A”);
      queue.offer(“B”);
      queue.offer(“C”);

    while (!queue.isEmpty()) {
        System.out.println(queue.poll());
      }

Deque

  特點:
   1. Deque是一個Queue的子接口,是一個雙端隊列,支持在兩端插入和移除元素
   2. deque支持索引值直接存取。
   3. Deque頭部和尾部添加或移除元素都非常快速。但是在中部安插元素或移除元素比較費時。
   4. 插入、刪除、獲取操作支持兩種形式:快速失敗和返回nulltrue/false
   5. 不推薦插入null元素,null作爲特定返回值表示隊列爲空

   常用方法
      xxxFirst xxxLast 支持從兩段插入和溢出還有查看, 並且有兩套方法

ArrayDeque

  1.底層數據是數組
   2.沒有實現List接口,所以不能夠通過索引來操作隊列

LinkedList

   1.底層數據結構是鏈表
   2.實現了List接口,具備List接口的功能,可以通過索引來獲取數據
   3.實現了Queue接口的功能,支持在對尾插入,對頭取出數據的特點,先進先出
   4.實現了Deque接口的功能,支持在兩段插入和刪除
   5.實現了棧結構,支持先進後出的存取數據

Set

  特點: 無序,唯一
   常用方法: 和Collection一模一樣
   遍歷方式: 和Collection一模一樣

HashSet

    底層數據結構是哈希表
     哈希表如何保證唯一?
     依賴hashcode和equals方法
       首先判斷hashCode是否相同
         不相同
           就存儲到集合中
         相同
           比較equals方法是否相同
         相同 就不存儲
           不相同就以鏈表的方式存儲到集合中

  哈希表結構是如何存儲數據的?
     根據對象本身計算出來的hash值進行存儲,這個hash和對象的hashCode的有關
     如果hash不同,存儲到哈希表中,如果hash值一樣,那麼比較equals方法,如果
     equals不同那麼就以鏈表的形式存儲在同一個hash索引的位置,如果存儲的鏈表
     長度過長,這個時候會自動調整爲紅黑樹,紅黑樹是一種自平衡的二叉樹,該樹查找的
     次數就是樹的深度,彌補了鏈表查找效率低的問題

TreeSet

  底層數據結構是自平衡的二叉樹
   二叉樹如何保證唯一?
       根據二叉樹的存儲特點
         首先第一個元素進來,作爲根節點存儲【類型檢查】
         第二個元素和第一個元素比較
         大了放在根的右邊
         小了放在根的左邊
         相等 不處理
   二叉樹如何保證可排序
       根據二叉樹的取的特點
         中序遍歷: 左根右
   已知 前序遍歷和中序遍歷 求後序遍歷
   自然排序
       使用無參構造方法 Comparable接口
   比較排序
       使用帶Comparator接口的參數
       實現類
       匿名內部類
   當同時使用自然排序和比較器排序時,比較器排序優先
注意標準的排序寫法

public int compare(Student s1, Student s2) {
						// 注:總分相同等情況下按照語文成績排序,其次是數學成績、英語成績、年齡、姓名
						double num1 = s1.getTotalScore() - s2.getTotalScore();
						double num2 = (num1 == 0) ? s1.getChineseScore() - s2.getChineseScore() :  num1;
						double num3 = (num2 == 0) ? s1.getMathScore() - s2.getMathScore() : num2;
						double num4 = (num3 == 0) ? s1.getEnglishScore() - s2.getEnglishScore() : num3;
						double num5 = (num4 == 0) ? s1.getAge() - s2.getAge() : num4;
						double num6 = (num5 == 0) ? s1.getName().compareTo(s2.getName()) : num5;
						return (num6 < 0) ? -1 : ( (num6 == 0) ? 0 : 1 );
					}

  HashSet去重複 數據庫的一個關鍵字 distinct
   TreeSet排序 數據庫的一個語法 order by

   LinkedHashSet
      底層數據結構是鏈表 + 哈希表,鏈表保證元素有序,哈希表保證元素唯一
      讓無序的set集合變有序
   EnumSet
      底層數據結構是枚舉數組,枚舉本身就是唯一的,方便

雙列集合

Map

Map<K,V>(接口)
  Map集合的特點
     1.能夠存儲唯一的列的數據(唯一,不可重複) Set
     2.能夠存儲可以重複的數據(可重複) Collection
     3.值的順序取決於鍵的順序
     4.鍵和值都是可以存儲null元素的

    一個映射不能包含重複的鍵。
     每個鍵最多隻能映射到一個值。

  常用功能
   1.添加功能
     V put(K key, V value)
     void putAll(Map<? extends K,? extends V> m)
   2.刪除功能
     V remove(Object key)
     void clear()
   3.遍歷功能
     Set keySet()
     Collection values()
     Set<Map.Entry<K,V>> entrySet()
   4.獲取功能
     V get(Object key)
   5.判斷功能
     boolean containsKey(Object key)
     boolean containsValue(Object value)
     boolean isEmpty()
   6.修改功能
     V put(K key, V value)
     void putAll(Map<? extends K,? extends V> m)
   7.長度功能
     int size()
   遍歷方式
     Set keySet() 獲取鍵的集合
     Collection values() 獲取值的集合
     Set<Map.Entry<K,V>> entrySet()

	interface Entry<K,V> {
			  			K getKey();
			   			V getValue();
			   			V setValue(V value);
			  		}

    兩種常用遍歷方式
       方式1:根據Key查找Value Set set = map.keySet()
       獲取所有Key的集合
       遍歷Key的集合,獲取到每一個Key
       根據Key查找Value
       方式2:根據鍵值對對象找鍵和值
           Set<Map.Entry<Key, Value>> set = map.entrySet();
       獲取所有鍵值對對象的集合
       遍歷鍵值對對象的集合,獲取到每一個鍵值對對象
       根據鍵值對對象找鍵和值

HashMap

    底層數據結構和HashSet一樣

Hashtable

    底層數據結構是哈希表,線程安全,效率低,不允許null值null鍵

TreeMap

    底層數據結構和TreeSet一樣

LinkedHashMap

    底層數據結構是哈希表和鏈表

WeakHashMap

    以弱鍵存儲的哈希表結構Map集合

EnumMap

    枚舉映射在內部表示爲數組。此表示形式非常緊湊且高效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章