Java集合

一、 認識集合

1、Collection接口是集合類的根接口,Java中沒有提供這個接口的直接的實現類。但是卻讓其被繼承產生了兩個接口,就是SetListSet中不能包含重複的元素。List是一個有序的集合,可以包含重複的元素,提供了按索引訪問的方式。

2、MapJava.util包中的另一個接口,它和Collection接口沒有關係,是相互獨立的,但是都屬於集合類的一部分。Map包含了key-value對。Map不能包含重複的key,但是可以包含相同的value


Collection                                          
 ├ List                    
 │   ├ LinkedList
 │   ├ ArrayList
 │   └ Vector
 │      └ Stack
 ├ Queue
 └ Set
    ├ HashSet
    ├ TreeSet

Map
├ Hashtable
├ HashMap
└ WeakHashMap

二、幾種重要的接口和類簡介

1、List(有序、可重複)

List裏存放的對象是有序的,同時也是可以重複的,List關注的是索引,擁有一系列和索引相關的方法,查詢速度快。因爲往list集合裏插入或刪除數據時,會伴隨着後面數據的移動,所有插入刪除數據速度慢。

2、Set(無序、不能重複)

Set裏存放的對象是無序的,不能重複的,集合中的對象不按特定的方式排序,只是簡單地把對象加入集合中。

3、Map(鍵值對、鍵唯一、值不唯一)

Map集合中存儲的是鍵值對,鍵不能重複,值可以重複。根據鍵得到值,對map集合遍歷時先得到鍵的set集合,對set集合進行遍歷,得到相應的值。

對比如下:

 

 

是否有序

是否允許元素重複

Collection

 

 

 

List

 

Set

AbstractSet

 

HashSet

 

 

 

TreeSet

是(用二叉排序樹)

 

Map

AbstractMap

使用key-value來映射和存儲數據,key必須唯一,value可以重複

 

HashMap

 

 

 

TreeMap

是(用二叉排序樹)

 

 

三、集合的輸出(遍歷

1、 在類集中提供了以下四種的常見輸出方式:

1)Iterator:迭代輸出,是使用最多的輸出方式。

Iterator,所有的集合類,都實現了Iterator接口,這是一個用於遍歷集合中元素的接口,主要包含以下三種方法:

1.hasNext()是否還有下一個元素。

2.next()返回下一個元素。

3.remove()刪除當前元素

代碼:

Iterator it = arr.iterator();

while(it.hasNext()){ object o =it.next(); ...}

2)ListIterator:是Iterator的子接口,專門用於輸出List中的內容。

3)foreach輸出:JDK1.5之後提供的新功能,可以輸出數組或集合。

foreach的形式: for(int i:arr){...}

4)for循環

 for的形式:for(int i=0;i<arr.size();i++){...}

四、Map集合

實現類:HashMap、Hashtable、LinkedHashMap和TreeMap

1、HashMap(元素不能重複,且沒有順序) HashMap是最常用的Map,它根據鍵的HashCode值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度,遍歷時,取得數據的順序是完全隨機的。因爲鍵對象不可以重複,所以HashMap最多隻允許一條記錄的鍵爲Null,允許多條記錄的值爲Null,是非同步的

2、HashtableHashtable與HashMap類似,是HashMap的線程安全版,它支持線程的同步,即任一時刻只有一個線程能寫Hashtable,因此也導致了Hashtale在寫入時會比較慢,它繼承自Dictionary類,不同的是它不允許記錄的鍵或者值爲null,同時效率較低。

3、ConcurrentHashMap線程安全,並且鎖分離。ConcurrentHashMap內部使用段(Segment)來表示這些不同的部分,每個段其實就是一個小的hash table,它們有自己的鎖。只要多個修改操作發生在不同的段上,它們就可以併發進行。

4、LinkedHashMapLinkedHashMap保存了記錄的插入順序,在用Iteraor遍歷LinkedHashMap時,先得到的記錄肯定是先插入的,在遍歷的時候會比HashMap慢,有HashMap的全部特性。

5、TreeMap(有序)TreeMap實現SortMap接口,能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序(自然順序),也可以指定排序的比較器,當用Iterator遍歷TreeMap時,得到的記錄是排過序的。不允許key值爲空,非同步的。

五、Map遍歷

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class TestMap {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "a");
        map.put(2, "b");
        map.put(3, "ab");
        map.put(4, "ab");
        map.put(4, "ab");// 和上面相同 , 會自己篩選
        System.out.println(map.size());
        // 第一種:
        /*
         * Set<Integer> set = map.keySet(); //得到所有key的集合
         * 
         * for (Integer in : set) { String str = map.get(in);
         * System.out.println(in + "     " + str); }
         */
        System.out.println("第一種:通過Map.keySet遍歷key和value:");
        for (Integer in : map.keySet()) {
            //map.keySet()返回的是所有key的值
            String str = map.get(in);//得到每個key多對用value的值
            System.out.println(in + "     " + str);
        }
        // 第二種:
        System.out.println("第二種:通過Map.entrySet使用iterator遍歷key和value:");
        Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
             Map.Entry<Integer, String> entry = it.next();
               System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
        }
        // 第三種:推薦,尤其是容量大時
        System.out.println("第三種:通過Map.entrySet遍歷key和value");
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            //Map.entry<Integer,String> 映射項(鍵-值對)  有幾個方法:用上面的名字entry
            //entry.getKey() ;entry.getValue(); entry.setValue();
            //map.entrySet()  返回此映射中包含的映射關係的 Set視圖。
            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);
        }
    }
}

六、主要實現類區別小結

1、Vector和ArrayList

1),vector是線程同步的,所以它也是線程安全的,而arraylist是線程異步的,是不安全的。如果不考慮到線程的安全因素,一般用arraylist效率比較高。

2),如果集合中的元素的數目大於目前集合數組的長度時,vector增長率爲目前數組長度的100%,而arraylist增長率爲目前數組長度的50%。如果在集合中使用數據量比較大的數據,用vector有一定的優勢。

3),如果查找一個指定位置的數據,vector和arraylist使用的時間是相同的,如果頻繁的訪問數據,這個時候使用vector和arraylist都可以。而如果移動一個指定位置會導致後面的元素都發生移動,這個時候就應該考慮到使用linklist,因爲它移動一個指定位置的數據時其它元素不移動。

ArrayList 和Vector是採用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加和插入元素,都允許直接序號索引元素,但是插入數據要涉及到數組元素移動等內存操作,所以索引數據快,插入數據慢,Vector由於使用了synchronized方法(線程安全)所以性能上比ArrayList要差,LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行向前或向後遍歷,但是插入數據時只需要記錄本項的前後項即可,所以插入數度較快。

2、ArrayList和LinkedList

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

2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因爲LinkedList要移動指針。

3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因爲ArrayList要移動數據。 這一點要看實際情況的。若只對單條數據插入或刪除,ArrayList的速度反而優於LinkedList。但若是批量隨機的插入刪除數據,LinkedList的速度大大優於ArrayList. 因爲ArrayList每插入一條數據,要移動插入點及之後的所有數據。

3、HashMap與TreeMap

1、 HashMap通過hashcode對其內容進行快速查找,而TreeMap中所有的元素都保持着某種固定的順序,如果你需要得到一個有序的結果你就應該使用TreeMap(HashMap中元素的排列順序是不固定的)。

2、在Map 中插入、刪除和定位元素,HashMap是最好的選擇。但如果您要按自然順序或自定義順序遍歷鍵,那麼TreeMap會更好。使用HashMap要求添加的鍵類明確定義了hashCode()和 equals()的實現。

兩個map中的元素一樣,但順序不一樣,導致hashCode()不一樣。

同樣做測試:

在HashMap中,同樣的值的map,順序不同,equals時,false;

而在treeMap中,同樣的值的map,順序不同,equals時,true,說明,treeMap在equals()時是整理了順序了的。

HashTable與HashMap

1、同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的。

2、HashMap允許存在一個爲null的key,多個爲null的value 。

3、hashtable的key和value都不允許爲null。

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