java集合統述

戈馬書生發表於2020-10-26

JAVA集合

集合可以看作是一種容器,用來儲存物件(Java集合中實際存放的只是物件的引用,每個集合元素都是一個引用變數)。
Java集合框架圖
由上圖可以看出主要有兩種型別的容器

  • 集合(Collection),儲存一個元素集合
  • 圖(Map),儲存鍵/值對的對映
    集合框架是一個用來代表和操縱集合統一的架構。所有的集合框架都包括如下內容:
  • 介面:是代表集合的抽象資料型別,類如List、Set、‘Map等,之所以定義多個介面,是為了以不同的方式操作集合物件。
  • 實現類:是集合介面的具體實現。它們可以重複利用的資料結構。例如:ArrayList、LinkedList、HashMap、HashSet。
  • 演算法:是實現介面物件裡的方法執行的一些有用的計算。例如:搜尋和排序。這些演算法被稱為多型,是因為可以在相似的介面上有不同的實現。

除了集合,該框架也定義了幾個Map介面和實現類。Map也是儲存物件的容器(鍵/值)。

集合(Collection)

集合(collection)有三種子型別,List、Set、Queue。

相關的介面:

介面介面描述
CollectionCollection 是最基本的集合介面,一個 Collection 代表一組 Object,即 Collection 的元素, Java不提供直接繼承自Collection的類,只提供繼承於的子介面(如List和set)。
Collection 介面儲存一組不唯一,無序的物件。
ListList介面是一個有序的 Collection,使用此介面能夠精確的控制每個元素插入的位置,能夠通過索引(元素在List中位置,類似於陣列的下標)來訪問List中的元素,第一個元素的索引為 0,而且允許有相同的元素。
List 介面儲存一組不唯一,有序(插入順序)的物件。
SetSet具有與Collection完全一樣的介面。只是行為上不同,Set不儲存重複的資料
SortedSet繼承Set儲存有序的集合

** Set和List的區別

  1. Set 介面例項儲存的是無序的,不重複的資料。List 介面例項儲存的是有序的,可以重複的元素。
  2. Set檢索效率低下,刪除和插入效率高,插入和刪除不會引起元素位置改變 <實現類有HashSet,TreeSet>。
  3. List和陣列類似,可以動態增長,根據實際儲存的資料的長度自動增長List的長度。查詢元素效率高,插入刪除效率低,因為會引起其他元素位置改變 <實現類有ArrayList,LinkedList,Vector> 。

相關實現類:

類描述
AbstractCollection實現了大部分的集合介面
AbstractList繼承AbstractCollection並且實現了大部分List介面
AbstractSequentialList繼承AbstractList,提供了對資料元素的鏈式方位而不是隨機訪問
LinkedList該類實現了List介面,允許Null元素。主要用於建立連結串列資料結構,該類是非同步的(多執行緒是不安全的)。查詢效率緩慢
ArrayList該類也是實現了List的介面,實現了可變大小的陣列,隨機訪問和遍歷元素時,提供更好的效能。該類也是非同步的(多執行緒是不安全的)。插入刪除效率低。
AbstractSet繼承AbstractCollaction並實現了大部分Set介面
HashSet該類實現了Set介面,不允許出現重複資料,不保證集合中元素的順序,允許值為null(但是最多隻能有一個)
LinkedHashSet具有可預知迭代順序的Set介面的雜湊表和連結串列的實現
TreeSet該類實現了Set介面,可以實現排序等功能
vector該類和ArrayList非常相似,但是該類時同步的。可以在多執行緒情況下使用。預設擴容時原來的2倍
Stack棧是Vector的一個子類,它實現了一個標準的後進先出的棧
Dictionary是一個抽象類,用來儲存鍵值對,作用和Map相似
HashTable是Dictionary的一個子類
properties繼承於HashTable,表示一個持久的屬性集,屬性列表中每一個鍵及對應值都是一個字串
BitSet一個BitSet類建立一種特殊型別的陣列來儲存位值。BitSet中陣列大小會隨需要增加

圖(Map)

儲存鍵值對。

相關的介面:

介面介面描述
Mapmap介面儲存一組鍵值物件,提供key(鍵)到value(值)的對映
Map.Entry描述在一個Map中的一個元素(鍵/值),是一個Map的內部類
SortedMap繼承Map介面,使Key保持升序排列

相關實現類:

類描述
AbstractMap實現了大部分的Map介面
HashMap該類繼承了AbstractMap,是一個雜湊表,它儲存的內容是鍵值對(key-value)對映。
該類實現了Map介面,根據鍵的hashcode值儲存資料,具有很快的訪問速度,最多允許一條記錄的鍵為null,不支援多執行緒同步
TreeMap繼承AbstractMap,並且使用了一棵樹
WeakHashMap繼承AbstractMap類,使用弱金鑰的雜湊表
LinkedHashMap繼承於HashMap,使用元素的自然順序對資料進行排序
IdentityHashMap繼承AbstractMap,比較文件時使用引用相等

集合的演算法

集合框架定義了幾種演算法,可用於集合和對映。這些演算法被定義為集合類的靜態方法。

在嘗試比較不相容的型別時,一些方法能夠丟擲 ClassCastException異常。當試圖修改一個不可修改的集合時,丟擲UnsupportedOperationException異常。

集合定義三個靜態的變數:EMPTY_SET,EMPTY_LIST,EMPTY_MAP的。這些變數都不可改變。

迭代器

一般遍歷陣列都是採用for迴圈或者增強for,這兩個方法也可以用在集合框架,但是還有一種方法是採用迭代器遍歷集合框架,它是一個物件,實現了Iterator 介面或 ListIterator介面。

遍歷List:

import java.util.*;
 
public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一種遍歷方法使用 For-Each 遍歷 List
     for (String str : list) {            //也可以改寫 for(int i=0;i<list.size();i++) 這種形式
        System.out.println(str);
     }
 
     //第二種遍歷,把連結串列變為陣列相關的內容進行遍歷
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //這裡也可以改寫為  for(String str:strArray) 這種形式
     {
        System.out.println(strArray[i]);
     }
     
    //第三種遍歷 使用迭代器進行相關遍歷
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判斷下一個元素之後有值
     {
         System.out.println(ite.next());
     }
 }
}

遍歷Map

import java.util.*;
 
public class Test{
     public static void main(String[] args) {
      Map<String, String> map = new HashMap<String, String>();
      map.put("1", "value1");
      map.put("2", "value2");
      map.put("3", "value3");
      
      //第一種:普遍使用,二次取值
      System.out.println("通過Map.keySet遍歷key和value:");
      for (String key : map.keySet()) {
       System.out.println("key= "+ key + " and value= " + map.get(key));
      }
      
      //第二種
      System.out.println("通過Map.entrySet使用iterator遍歷key和value:");
      Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
      while (it.hasNext()) {
       Map.Entry<String, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
      
      //第三種:推薦,尤其是容量大時
      System.out.println("通過Map.entrySet遍歷key和value");
      for (Map.Entry<String, String> entry : map.entrySet()) {
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
    
      //第四種
      System.out.println("通過Map.values()遍歷所有的value,但不能遍歷key");
      for (String v : map.values()) {
       System.out.println("value= " + v);
      }
     }
}

站在巨人的肩上:java集合框架|菜鳥教程