Java高階特性之集合

跟著Jacob一起敲程式碼發表於2020-05-27

Java集合框架

一、Java集合框架概述

1、陣列與集合的區別:

1)陣列長度不可變化而且無法儲存具有對映關係的資料;集合類用於儲存數量不確定的資料,以及儲存具有對映關係的資料。

2)陣列元素既可以是基本型別的值,也可以是物件;集合只能儲存物件。

2、Java集合類主要由兩個根介面Collection和Map派生出來的,Collection派生出了三個子介面:List、Set、Queue(Java5新增的佇列),因此Java集合大致也可分成List(有序、可重複集合、可直接根據元素的索引來訪問)、Set(無序、不可重複集合、只能根據元素本身來訪問)、Queue(佇列集合)、Map(儲存key-value對的集合,可根據元素的key來訪問value)這四種。

二、Java集合常見介面及實現類

1、Collection介面常見方法

2、List集合

實現List介面的集合主要有:ArrayList、LinkedList、Vector、Stack。

它們都可以容納所有型別的物件,包括 null,允許重複,並且都保證元素的儲存順序。可重複,有順序)

1)ArrayList

 ArrayList 對陣列進行了封裝,實現了長度可變的陣列(動態陣列),和陣列採用相同儲存方式,在記憶體中分配連續的空間,它的優點在於遍歷元素和隨即訪問元素的效率比較高。

ArrayList特點:執行緒不安全,查詢速度快底層資料結構是陣列結構擴容增量:原容量的 1.5倍 ArrayList的容量為10,一次擴容後是容量為15

2)LinkedList

LinkedList是List介面的另一個實現,除了可以根據索引訪問集合元素外,LinkedList還實現了Deque介面,可以當作雙端佇列來使用,也就是說,既可以當作“棧”使用,又可以當作佇列使用。

 LinkedList 採用連結串列儲存方式,優點在於插入、刪除元素時效率比較高,它提供了額外的 addFirst()、addLast()、removeFirst()和 removeLast()等方法,可以在LinkedList 的首部或尾部進行插入或者刪除操作。 

3)Vector

與ArrayList相似,但是Vector是同步的。所以說Vector是執行緒安全的動態陣列。它的操作與ArrayList幾乎一樣。

3、Set集合

實現Set集合的介面主要有:HashSet、TreeSet、LinkedHashSet;

Set集合與Collection的方法相同,由於Set集合不允許儲存相同的元素,所以如果把兩個相同元素新增到同一個Set集合,則新增操作失敗,新元素不會被加入,add()方法返回false。(無序、不重複)

1)HashSet

HashSet是按照hash演算法來儲存元素的,因此具有很好的存取和查詢效能。

 HashSet儲存原理如下:

  當向HashSet集合儲存一個元素時,HashSet會呼叫該物件的hashCode()方法得到其hashCode值,然後根據hashCode值決定該物件的儲存位置。HashSet集合判斷兩個元素相等的標準是(1)兩個物件通過equals()方法比較返回true;(2)兩個物件的hashCode()方法返回值相等。因此,如果(1)和(2)有一個不滿足條件,則認為這兩個物件不相等,可以新增成功。如果兩個物件的hashCode()方法返回值相等,但是兩個物件通過equals()方法比較返回false,HashSet會以鏈式結構將兩個物件儲存在同一位置,這將導致效能下降,因此在編碼時應避免出現這種情況。

HashSet查詢原理如下:

  基於HashSet以上的儲存原理,在查詢元素時,HashSet先計算元素的HashCode值(也就是呼叫物件的hashCode方法的返回值),然後直接到hashCode值對應的位置去取出元素即可,這就是HashSet速度很快的原因。

HashSet特點:

       不能保證元素的順序;集合元素值可以是null;執行緒不安全,存取速度快;底層實現是一個HashMap(儲存資料),實現Set介面;預設初始容量為16;載入因子為0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容;擴容增量:原容量的 1 倍; HashSet的容量為16,一次擴容後是容量為32。

2)LinkedHashSet

LinkedHashSet是HashSet的一個子類,具有HashSet的特性,也是根據元素的hashCode值來決定元素的儲存位置。但它使用連結串列維護元素的次序,元素的順序與新增順序一致。由於LinkedHashSet需要維護元素的插入順序,因此效能略低於HashSet,但在迭代訪問Set裡的全部元素時由很好的效能。

3)TreeSet

TreeSet可以保證元素處於排序狀態,它採用紅黑樹的資料結構來儲存集合元素。TreeSet支援兩種排序方法:自然排序和定製排序,預設採用自然排序。

♦ 自然排序

  TreeSet會呼叫集合元素的compareTo(Object obj)方法來比較元素的大小關係,然後將元素按照升序排列,這就是自然排序。如果試圖將一個物件新增到TreeSet集合中,則該物件必須實現Comparable介面,否則會丟擲異常。當一個物件呼叫方法與另一個物件比較時,例如obj1.compareTo(obj2),如果該方法返回0,則兩個物件相等;如果返回一個正數,則obj1大於obj2;如果返回一個負數,則obj1小於obj2。

♦ 定製排序

  想要實現定製排序,需要在建立TreeSet集合物件時,提供一個Comparator物件與該TreeSet集合關聯,由Comparator物件負責集合元素的排序邏輯。

綜上:自然排序實現的是Comparable介面,定製排序實現的是Comparator介面。

4、Map集合

Map介面採用鍵值對Map<K,V>的儲存方式,儲存具有對映關係的資料,因此,Map集合裡儲存兩組值,一組值用於儲存Map裡的key,另外一組值用於儲存Map裡的value,key和value可以是任意引用型別的資料。key值不允許重複,可以為null。如果新增key-value對時Map中已經有重複的key,則新新增的value會覆蓋該key原來對應的value。

常用實現類主要有HashMap、LinkedHashMap、TreeMap。

1)HashMap

對於HashMap而言,key是唯一的,不可以重複的所以,以相同的key 把不同的value插入到 Map中會導致舊元素被覆蓋,只留下最後插入的元素不過,同一個物件可以作為值插入到map中,只要對應的key不一樣

 HashMap由陣列+連結串列組成的,陣列是HashMap的主體,連結串列則是主要為了解決雜湊衝突而存在的

 HashMap工作原理如下:

 

  HashMap基於hashing原理,通過put()和get()方法儲存和獲取物件。當我們將鍵值對傳遞給put()方法時,它呼叫建物件的hashCode()方法來計算hashCode值,然後找到bucket位置來儲存值物件。當獲取物件時,通過建物件的equals()方法找到正確的鍵值對,然後返回物件。HashMap使用連結串列來解決碰撞問題,當發生碰撞了,物件將會儲存在連結串列的下一個節點中。

HashMap特點:

  • Map提供了一種對映關係,元素是以鍵值對(key-value)的形式儲存的,能根據key快速查詢value;
  • Map中的鍵值對以Entry型別的物件例項形式存在;
  • key值不能重複,value值可以重複;
  • keyvalue是多(一)對一的關係;
  • Map介面提供了返回key值集合、value值集合、Entry值集合,的方法;
  • Map支援泛型,形式如:Map<K,V>;
  • 預設初始容量為16
  • 載入因子為0.75:即當 元素個數 超過 容量長度的0.75倍 時,進行擴容
  • 擴容增量:原容量的 1 倍。

2)LinkedHashMap

LinkedHashMap使用雙向連結串列來維護key-value對的次序(其實只需要考慮key的次序即可),該連結串列負責維護Map的迭代順序,與插入順序一致,因此效能比HashMap低,但在迭代訪問Map裡的全部元素時有較好的效能。

大多數情況下,只要不涉及執行緒安全問題,Map基本都可以使用HashMap,不過HashMap有一個問題,是迭代HashMap的順序並不是HashMap放置的順序也就是無序。HashMap的這一缺點往往會帶來困擾,因為有些場景,我們期待一個有序的Map。這個時候,LinkedHashMap就閃亮登場了,它雖然增加了時間和空間上的開銷,但是通過維護一個執行於所有條目的雙向連結串列,LinkedHashMap保證了元素迭代的順序該迭代順序可以是插入順序或者是訪問順序。

LinkedHashMap可以認為是HashMap+LinkedList即它既使用HashMap運算元據結構,又使用LinkedList維護插入元素的先後順序。

LinkedHashMap的基本實現思想就是----多型

3)TreeMap

TreeMap是SortedMap的實現類,是一個紅黑樹的資料結構,每個key-value對作為紅黑樹的一個節點。TreeMap儲存key-value對時,需要根據key對節點進行排序。TreeMap也有兩種排序方式:

  ♦ 自然排序:TreeMap的所有key必須實現Comparable介面,而且所有的key應該是同一個類的物件,否則會丟擲ClassCastException。

  ♦ 定製排序:建立TreeMap時,傳入一個Comparator物件,該物件負責對TreeMap中的所有key進行排序。

TreeMap特點:

       ·TreeMap是非執行緒安全的;

       ·TreeMap是用鍵來進行升序順序來排序的。通過Comparable 或 Comparator來排序;

       ·HashMap一樣,如果插入重複的元素,後面的元素會覆蓋前面的
       ·鍵不可以為null(如果比較器對null做了處理,就可以為null),但是值可以為null。

5、遍歷

第一種:for迴圈遍歷

1 for (int i = 0; i < heros.size(); i++) {
2             Hero h = heros.get(i);
3             System.out.println(h);
4         }

第二種:迭代器遍歷

 1 System.out.println("--------使用while的iterator-------");
 2         Iterator<Hero> it= heros.iterator();
 3         //從最開始的位置判斷"下一個"位置是否有資料
 4         //如果有就通過next取出來,並且把指標向下移動
 5         //直到"下一個"位置沒有資料
 6         while(it.hasNext()){
 7             Hero h = it.next();
 8             System.out.println(h);
 9         }
10         //迭代器的for寫法
11         System.out.println("--------使用for的iterator-------");
12         for (Iterator<Hero> iterator = heros.iterator(); iterator.hasNext();) {
13             Hero hero = (Hero) iterator.next();
14             System.out.println(hero);
15         }

 第三種:增強for迴圈

1 System.out.println("--------增強型for迴圈-------");
2         for (Hero h : heros) {
3             System.out.println(h);
4         }

 

相關文章