Java 集合框架

GarU25 8年前發布 | 8K 次閱讀 Java 鏈表 Java開發

Java集合框架大致可以分為五個部分:List列表,Set集合、Map映射、迭代器、工具類

List 接口通常表示一個列表(數組、隊列、鏈表

棧),其中的元素 可以重復 的是:ArrayList 和LinkedList,另外還有不常用的Vector。LinkedList實現來Queue接口,因此也可以作為隊列使用。

Set接口通常表示一個集合,其中的元素 不可以重復 (通過hashcode和equals函數保證),常用的實現類有HashSet和TreeSet

Map是一個 映射接口 ,其中的每個元素都是一個 key-value鍵值對 ,同樣抽象類AbstractMap通過適配器模式實現了Map接口中的大部分函數,TreeMap

HashMap、WeakHashMap等實現類都通過繼承AbstractMap實現的,另外,不常用的HashTable直接實現了Map接口。

Iterator是遍歷集合的迭代器(不能遍歷Map,只用來遍歷Collection),Collection的實現類都實現了iterator()函數,它返回一個Iterator對象,用來遍歷集合,ListIterator則專門用來遍歷List。

ArrayList

ArrayList的內部實現是基于基礎的對象數組的

特點:

  • 允許null元素

  • 順序表

  • 線程不同步、查詢速度快、增刪

  • 大小可變滿

LinkedList

LinkedList: 內部采用鏈表來存儲元素,支持快速插入/刪除元素,但不支持高效地隨機訪問

一般大家都知道ArrayList和LinkedList的大致區別:

1.ArrayList是實現了基于動態數組的數據結構,LinkedList基于鏈表的數據結構。

2.對于隨機訪問get和set,ArrayList優于LinkedList,因為LinkedList要移動指針。

3.對于新增和刪除操作add和remove,LinedList比較占優勢,因為ArrayList要移動數據。 ArrayList的內部實現是基于基礎的對象數組的 , LinkedList中的get方法是按照順序從列表的一端開始檢查,直到另外一端。對LinkedList而言,訪問列表中的某個指定元素沒有更快的方法了。 它們之間最主要的區別在于ArrayList是可改變大小的數組,而LinkedList是雙向鏈接串列(doubly LinkedList) ,因為Array是基于索引(index)的數據結構,它使用索引在數組中搜索和讀取數據是很快的。Array獲取數據的時間復雜度是O(1),但是要刪除數據卻是開銷很大的,因為這需要重排數組中的所有數據。

public class ArraylistandLinkedlist {
    public static final int N = 50000;
    public static List values;
    static {
        Integer vals[] = new Integer[N];
        Random r = new Random();
        for (int i = 0, currval = 0; i < N; i++) {
            vals[i] = new Integer(currval);
            currval += r.nextInt(100) + 1;
        }
        values = Arrays.asList(vals);
    }
    static long timeList(List lst) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < N; i++) {
            int index = Collections.binarySearch(lst, values.get(i));
            if (index != i)
                System.out.println("***錯誤***");
        }
        return System.currentTimeMillis() - start;
    }
    public static void main(String args[]) {
        System.out.println("ArrayList消耗時間:" + timeList(new ArrayList(values)));
        System.out.println("LinkedList消耗時間:" + timeList(new LinkedList(values)));
    }
}

HashSet

HashSet實現了Set接口,它 不允許 集合中有 重復的值 ,當我們提到HashSet時,第一件事情就是在將對象存儲在HashSet之前, 要先確保對象 重寫equals()和hashCode()方法 ,這樣才能比較對象的值是否相等,以確保set中沒有儲存相等的對象。如果我們沒有重寫這兩個方法,將會使用這個方法的默認實現。

特點

  • 線程同步
  • 不允許重復的值

HashMap

HashMap實現了Map接口,Map接口對鍵值對進行映射。 Map中不允許重復的鍵 。Map接口有兩個基本的實現,HashMap和TreeMap。TreeMap保存了對象的排列次序,而HashMap則不能。 HashMap允許鍵和值為null。 HashMap是非synchronized的,但collection框架提供方法能保證HashMap synchronized,這樣多個線程同時訪問HashMap時,能保證只有一個線程更改Map。

HashMap是一種<key,value>的存儲結構,能夠快速將key的數據put方式存儲起來,然后很快的通過get取出來”,“HashMap不是線程安全的, HashTable是線程安全的,通過synchronized實現的

簡單的說HashMap的存儲結構是由 數組和鏈表 共同完成的

HashMap是Y軸方向是數組,X軸方向就是鏈表的存儲方式

HashTable

HashMap和Hashtable都實現了Map接口,但決定用哪一個之前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。

HashMap幾乎可以等價于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受為null的鍵值(key)和值(value), 而Hashtable則不行)。 HashMap是非synchronized,而Hashtable是synchronized ,這意味著Hashtable是線程安全的,多個線程可以共享一個Hashtable;而如果沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。另一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以當有其它線程改變了HashMap的結構(增加或者移除元素),將會拋出ConcurrentModificationException,但迭代器本身的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這并不是一個一定發生的行為,要看JVM。

** 由于Hashtable是線程安全的也是synchronized,所以在單線程環境下它比HashMap要慢。如果你不需要同步,只需要單一線程,那么使用HashMap性能要好過Hashtable。HashMap不能保證隨著時間的推移Map中的元素次序是不變的。

public class HashmapAndHashTable {
    public static void main(String... args) {

        HashMap<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("cn", "中國");
        hashMap.put("us", "米國");
        hashMap.put("en", "英國");
        hashMap.put("","");

        System.out.println(hashMap);
        System.out.println("cn" + hashMap.get("cn"));
        System.out.println(hashMap.containsKey("cn"));
        System.out.println(hashMap.keySet());
        System.out.println(hashMap.isEmpty());

        Hashtable table = new Hashtable();
        table.put("key1", "value1");//鍵 和 值,
        table.put("key2", "value2");
        table.put("key3", "value3");//相當于堆棧 后進先出

        Enumeration e = table.keys();//創建枚舉
        while (e.hasMoreElements()) {//是否有元素
            String key = (String) e.nextElement();
            System.out.println(key + " : " + table.get(key));
        }
    }

}

 

來自:http://www.jianshu.com/p/32a1616fdf8c

 

 本文由用戶 GarU25 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!