天天看點

Java集合JAVA 集合

JAVA 集合

1.接口繼承關系和實作

集合類存放于 Java.util 包中,主要有 3 種:set(集)、list(清單包含 Queue)和 map(映射)。

1. Collection:Collection 是集合 List、Set、Queue 的最基本的接口。 2. Iterator:疊代器,可以通過疊代器周遊集合中的資料 3. Map:是映射表的基礎接口

Java集合JAVA 集合
Java集合JAVA 集合

2.List

Java 的 List 是非常常用的資料類型。List 是有序的 Collection。Java List 一共三個實作類: 分别是 ArrayList、Vector 和 LinkedList。

2.1 ArrayList(數組)

ArrayList 是最常用的 List 實作類,内部是通過數組實作的,它允許對元素進行快速随機通路。數組的缺點是每個元素之間不能有間隔, 當數組大小不滿足時需要增加存儲能力,就要将已經有數組的資料複制到新的存儲空間中 。 當從 ArrayList 的中間位置插入或者删除元素時,需要對數組進行複制、移動、代價比較高。是以,它适合随機查找和周遊,不适合插入和删除 。

2.2 Vector(數組實作、線程同步)

Vector 與 ArrayList 一樣,也是通過數組實作的,不同的是 它支援線程的同步,即某一時刻隻有一 個線程能夠寫 Vector ,避免多線程同時寫而引起的不一緻性,但實作同步需要很高的花費,是以, 通路它比通路 ArrayList 慢。

2.3 LinkList(連結清單)

LinkedList 是用連結清單結構存儲資料的,很适合資料的動态插入和删除 ,随機通路和周遊速度比較慢。另外,他還提供了 List 接口中沒有定義的方法,專門用于操作表頭和表尾元素,可以當作堆棧、隊列和雙向隊列使用。

3.Set

Set 注重獨一無二的性質,該體系集合用于存儲無序(存入和取出的順序不一定相同)元素, 值不能重 複 。對象的相等性本質是對象 hashCode 值(java 是依據對象的記憶體位址計算出的此序号)判斷 的, 如果想要讓兩個不同的對象視為相等的,就必須覆寫 Object 的 hashCode 方法和 equals 方 法。

哈希表邊存放的是哈希值。HashSet 存儲元素的順序并不是按照存入時的順序(和 List 顯然不同) 而是按照哈希值來存的是以取資料也是按照哈希值取得。元素的哈希值是通過元素的hashcode 方法來擷取的, HashSet 首先判斷兩個元素的哈希值,如果哈希值一樣,接着會比較 equals 方法 如果 equls 結果為 true ,HashSet 就視為同一個元素。如果 equals 為 false 就不是 同一個元素。 HashSet 通過 hashCode 值來确定元素在記憶體中的位置。 一個 hashCode 位置上可以存放多個元素 。

3.1 TreeSet(二叉樹)

1. TreeSet()是使用二叉樹的原理對新 add()的對象按照指定的順序排序(升序、降序),每增加一個對象都會進行排序,将對象插入的二叉樹指定的位置。 2. Integer 和 String 對象都可以進行預設的 TreeSet 排序,而自定義類的對象是不可以的, 自己定義的類必須實作 Comparable 接口,并且覆寫相應的 compareTo()函數 ,才可以正常使用。 3. 在覆寫 compare()函數時,要傳回相應的值才能使 TreeSet 按照一定的規則來排序 4. 比較此對象與指定對象的順序。如果該對象小于、等于或大于指定對象,則分别傳回負整數、零或正整數。

3.2 LinkHashSet(HashSet+LinkedHashMap)

對于 LinkedHashSet 而言,它繼承與 HashSet、又基于 LinkedHashMap 來實作的。 LinkedHashSet 底層使用 LinkedHashMap 來儲存所有元素,它繼承與 HashSet,其所有的方法操作上又與 HashSet 相同,是以 LinkedHashSet 的實作上非常簡單,隻提供了四個構造方法,并通過傳遞一個辨別參數,調用父類的構造器,底層構造一個 LinkedHashMap來實作,在相關操作上與父類 HashSet 的操作相同,直接調用父類 HashSet 的方法即可。

4. Map

HashMap 根據鍵的 hashCode 值存儲資料,大多數情況下可以直接定位到它的值,因而具有很快的通路速度,但周遊順序卻是不确定的。 HashMap 最多隻允許一條記錄的鍵為 null,允許多條記錄的值為 null。HashMap 非線程安全,即任一時刻可以有多個線程同時寫 HashMap,可能會導緻資料的不一緻。如果需要滿足線程安全,可以用 Collections 的 synchronizedMap 方法使HashMap 具有線程安全的能力,或者使用 ConcurrentHashMap。我們用下面這張圖來介紹HashMap 的結構。

4.1 ConcurrentHashMap

ConcurrentHashMap 和 HashMap 思路是差不多的,但是因為它支援并發操作,是以要複雜一些。整個 ConcurrentHashMap 由一個個 Segment 組成,Segment 代表”部分“或”一段“的意思,是以很多地方都會将其描述為分段鎖。注意,行文中,我很多地方用了“槽”來代表一個segment。 線程安全 簡單了解就是,ConcurrentHashMap 是一個 Segment 數組,Segment 通過繼承ReentrantLock 來進行加鎖,是以每次需要加鎖的操作鎖住的是一個 segment,這樣隻要保證每個 Segment 是線程安全的,也就實作了全局的線程安全

4.2 HashTable(線程安全)

Hashtable 是遺留類,很多映射的常用功能與 HashMap 類似,不同的是它承自 Dictionary 類,并且是線程安全的,任一時間隻有一個線程能寫 Hashtable,并發性不如 ConcurrentHashMap,因為 ConcurrentHashMap 引入了分段鎖。Hashtable 不建議在新代碼中使用,不需要線程安全的場合可以用 HashMap 替換,需要線程安全的場合可以用 ConcurrentHashMap 替換。

4.3 TreeMap(可排序)

TreeMap 實作 SortedMap 接口,能夠把它儲存的記錄根據鍵排序,預設是按鍵值的升序排序,也可以指定排序的比較器,當用 Iterator 周遊 TreeMap 時,得到的記錄是排過序的。如果使用排序的映射,建議使用 TreeMap。在使用 TreeMap 時,key 必須實作 Comparable 接口或者在構造 TreeMap傳入自定義的Comparator,否則會在運作時抛出 java.lang.ClassCastException 類型的異常。

4.4 LinkHashMap(記錄插入順序)

LinkedHashMap 是 HashMap 的一個子類,儲存了記錄的插入順序,在用 Iterator 周遊 LinkedHashMap 時,先得到的記錄肯定是先插入的,也可以在構造時帶參數,按照通路次序排序。

5 插入修改和周遊示例

5.1 ArrayList

package com.listDemo;

import java.util.ArrayList;

public class ArrayListDemo {

    public static void main(String[] args) {
            ArrayList<String> arr = new ArrayList<String>();

            //添加元素
            arr.add("1");
            arr.add("2");
            arr.add("3");

            //替換元素
            arr.set(1, "4");

            //删除元素
            arr.remove(0);

            //周遊
            for(String s :arr) {
                System.out.println(s);
            }
        }
    }
           

5.2 Map

package com.listDemo;

import java.util.*;

public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<String,String> hMap = new HashMap<String,String>();
        hMap.put("1", "1st");
        hMap.put("2", "2nd");
        hMap.put("3", "3rd");
        Collection cl = hMap.values();
        Iterator itr = cl.iterator();
        while (itr.hasNext()) {
           System.out.println(itr.next());
       }
    }
}
           

5.3 Set

package com.listDemo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetDemo {
    public static void main(String[] args) {
        //Set 集合存和取的順序不一緻。
        Set<String> hs = new HashSet<String>();
        hs.add("世界軍事");
        hs.add("兵器知識");
        hs.add("艦船知識");
        hs.add("漢和防務");
        System.out.println(hs);
        // [艦船知識, 世界軍事, 兵器知識, 漢和防務]
        Iterator<String> it = hs.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
           

繼續閱讀