List、Set、Map、Collections

1.List

概念
    單列集合 繼承自Collection,還是一個接口,不是一個實現類
集合框架體系圖

特點

  • 元素可重複
  • 有索引的
  • 元素有序(存元素的順序和去元素的順序是一樣的)

常用方法

  • void add(int index,E element) —>向指定索引添加元素
  • E get(int index) —>根據索引去元素
  • E remove(int index) —>根據索引刪元素
  • E set(int index,E element) —>用指定元素替代集合中指定位置的元素,返回被替換元素

實現類

ArrayList

概念

  • List實現類
  • 該集合的數據結構是一個數組

特點
    查詢快,增刪慢
方法
    沒有特有的方法

問題:
    ArrayList底層是數組,而數組長度是不可變的,但是ArrayList集合可以改變長度。它的底層是數組複製 —>copyOf —>System.ArrayCopy,所以操作元素比較慢!
    需求:往集合中添加5個元素,之後
        1.直接在集合開頭添加元素
        2. 在集合末尾添加元素
        3. 刪除集合第一個元素
        4. 刪除集合最後一個元素
當遇到上面這種需求,就有點瓜皮了。因此出現了下面的類

LinkedList

概念

  • List實現類
  • 查詢慢,增刪快
  • 該集合數據結構是一個鏈表結構(雙向鏈表)

特點

  • 元素有序
  • 有大量的特有方法去操作首尾元素

方法

  • void addFirst(E e) —>將指定元素插入到列表開頭。
  • void addLast(E e) —>將指定元素添加到列表結尾。
  • E getFirst() —>獲取第一個
  • E getLast() —>獲取最後一個
  • E removeFirst() —>刪除第一個
  • E removeLast() —>刪除最後一個
  • E pop() —>從此列表所表示的堆棧處彈出一個元素
  • void push(E e) —>將元素推入此列表所表示的堆棧
  • booleanisEmpty() —>如果列表不包含元素,則返回true。

總結
    從LinkedList中的Node對象來看,是一個雙鏈表,一個節點記錄着上一個節點的地址,也記錄着下一個節點的地址。


2.Collections

概念
    專門操作集合的工具類

特點
    方法全靜態使用時類名直接調用

方法

  • static void shuffle(List<?> list) —>打亂集合順序
  • sort(List list) —>將集合元素按照默認規則排序(按編碼表排序)
  • sort(List list, Comparator<? super T> c)
    Comparator是一個接口 —>比較器
    利用實現類使用,重寫Comparator中的方法
    int compare(T o1, T o2) —>前面的參數減去後面的參數(升序),反過來(降序)
//使用匿名內部類重寫Comparator中的方法int compare(T o1, T o2) 
public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return 01-02;//前面的參數減去後面的參數(升序)
            }
        });
    }

可變參
使用場景

  • 方法參數只確定參數類型,不確定方法參數
  • 本質是一個數組
    使用
    定義格式
public static void method(int...i){}

調用格式

method(1,2,3,4,5,6);//可以有很多

注意
    一個方法中只能定義一個可變參數
    可變參數可以和普通參數同時出現,但可變參數必須放在參數的最後邊


3.Set

概念
    方法(沒有特有方法)

使用
    根據實現類創建對象

特點

  • 不允許出現重複元素
  • 無序(LinkedHashSet是有序的)
  • 沒有索引,只能用迭代器和增強for遍歷

實現類

HashSet

特點

  • 不允許出現重複元素
  • 無序(存進去的順序和第一次取出來的順序不一致)
  • 沒有索引,只能用迭代器和增強for遍歷
  • 底層數據結構:哈希表結構

使用
    和Collection沒有區別
    HashSet本身沒有功能,依靠HashMap進行的

無參構造:默認初始容量爲16,加載因子爲0.75F
有參構造
    HashSet(int initialCapacity,float loadFactor)
        initialCapacity:初始容量
        loadFactor:指定的加載因子

但是通過分析源碼得知:創建HashSet無需指定初始容量和加載因子,因爲HashSet底層的算法計算後初始容量還是逃不了16的倍數。因此有參構造基本不用。

哈希表結構
哈希值概念:
    由計算機算出來的一個十進制數,可以理解爲對象的地址值(邏輯地址),內存分配給對象的地址值和哈希值沒啥關係。誰都不知道內存地址長什麼樣。
獲取哈希值
    對象.hashCode();
字符串哈希值
    String重寫了hashCode方法,計算的是字符串裏的內容的哈希值,特別注意的是字符串內容不相等,哈希值也有可能相等。比如:abc acD
結論
    內容一樣,哈希值一定一樣
    內容不一樣,哈希值也有可能一樣

hashSet如何保證數據唯一
    先獲取元素哈希值(存儲的元素類型重寫的hashCode)進行比較,如果哈希值相等 在比較內容,如果哈希值不相等,那麼內容肯定不相等。
    1.哈希值不一樣 直接存
    2.哈希值不一樣,但是內容不一樣,也可以存
    3.哈希值一樣,內容也一樣,證明完全是一個元素,HashSet直接去重複。
hashSet存儲自定義類型如何保證元素唯一
    1.在自定義類中重寫HashCode方法。
    2.重寫後的方法比較的是類中成員的哈希值。

哈希表
jdk8之前
    哈希表 = 數組+鏈表
jdk8之後
    哈希表 = 數組+鏈表(單向鏈)+紅黑樹

注意
    哈希表中的數組長度默認是16
    哈希值模16餘幾就存入對應下標
    如果鏈表長度超過8個,就會自動變成紅黑樹存儲。

哈希表儲存過程
當元素快超過了數組長度怎麼辦??
    加載因子
        0.75F ->如果往哈希表存元素達到了數組的百分之75,自動擴容2倍。擴容後下次存元素就不是模16餘了而是模32。以此類推…

LinkedHashSet

概念

  • 繼承自HashSet
  • 數據結構:鏈表+哈希表

特點

  • 元素唯一
  • 沒有索引
  • 有序

TreeSet

概念

  • Set實現類
  • 基於紅黑樹的實現

特點
    查詢快

作用
    使用元素的自然排序規則,對集合中的元素進行排序(內部會使用Comparator比較器進行默認的升序)

構造方法

  • TreeSet() —>默認升序
  • TreeSet(Comparator<? super E> comparator) —>指定排序規則。

4.Map

概念

  • 雙列集合頂級接口
  • 鍵必須唯一,不能重複.
  • 無序(但是實現類中有一個LinkedHashMap是有序的)
  • 沒有索引
  • 儲存元素的特點:鍵值對的形式

實現類

HashMap<K,V>

概念

  • 鍵必須唯一,不能重複.
  • 無序
  • 沒有索引
  • 儲存元素的特點:鍵值對的形式
  • 數據結構:哈希表

方法

  • V put(K key,V value):把指定的鍵與指定的值添加到Map集合
  • V remove(Object key):根據鍵刪除對應的值,返回被刪除的值
  • V get(Object key):根據鍵獲取值
  • boolean containsKey(Object key):判斷該集合中是否有此鍵
  • Set< K> keySet():獲取Map集合所有的鍵,存到Set集合中. —>用於遍歷HashMap集合
		//Set< K> keySet()
        Set<Integer> keySet = hashMap.keySet();
        for (Integer key : keySet) {
            System.out.println(key);
        }
  • Set<Map.Entry<K,V>> entrySet():獲取到Map集合中所有的鍵值對對象.—>用於遍歷HashMap集合
    Entry:是Map中的靜態的內部接口,記錄着Key和value的一個對象.
    Map.Entry獲取Entry

     K getKey():獲取key
     V getValue():獲取value

        //Set<Map.Entry<K,V>> entrySet()
        Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            int k = entry.getKey();
            String v = entry.getValue();

            System.out.println(k+"="+v);
        }

注意

  • 如果鍵重複,後添加的會把前添加的幹掉
  • Key值可以爲null

如何保證鍵唯一:
    鍵需要重寫hashCode和equals判斷過程和HashSet一摸一樣

HashMap存儲自定義類型:key爲自定義類型
如何保證Key唯一?

    重寫HashCode和equals

LinkedHashMap

概念
    是HashMap的子類

特點

  • 鍵唯一

  • 有序(數據結構 = 哈希表+鏈表)

  • 沒有索引

  • 用法和HashMap一毛一樣。

TreeMap

概念
    實現Map接口
    基於紅黑樹實現(查詢賊快)

作用
    可以對key進行排序

構造方法
    TreeMap():針對key進行自然排序,默認升序
    TreeMap(Comparator<? super K> comparator) :可以指定排序規則.

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