Java集合基礎知識總結(超級詳細)

一、數組Array和集合的區別

1、數組是大小固定的,並且同一個數組只能存放類型一樣的數據(基本類型/引用類型)

2、JAVA集合可以存儲和操作數目不固定的一組數據。

3、若程序時不知道究竟需要多少對象,需要在空間不足時自動擴增容量,則需要使用容器類庫,array不適用。 

注:使用相應的toArray()和Arrays.asList()方法可以相互轉換。

二、Java集合

集合類存放於Java.util包中。

集合類存放的都是對象的引用,而非對象本身,出於表達上的便利,我們稱集合中的對象就是指集合中對象的引用。

集合類型主要有三種:set(集)、list(列表)、map(映射)。

三、Collection接口

Collection是最基本的集合接口,一個Collection代表一組Object,即Collection的元素。Java SDK提供的類都是繼承自Collection的“子接口”如List和Set。

如何遍歷Collection中的每一個元素?不論Collection的實際類型如何,它都支持一個iterator()的方法,該方法返回一個迭代子,使用該迭代子即可逐一訪問Collection中每一個元素。典型的用法如下:

Iterator it = collection.iterator(); // 獲得一個迭代子
while(it.hasNext()) {
  Object obj = it.next(); // 得到下一個元素
}

由Collection接口派生的兩個接口是List和Set。

四、Set

Set接口同樣是Collection接口的一個子接口,Set不包含重複的元素。

HashSet:使用hashmap的一個集的實現。雖然集定義成無序,但必須存在某種方法能高效地找到一個對象。使用一個hashmap對象實現集的存儲和檢索操作時在固定時間內實現的。

TreeSet:在集中以升序對對象排序的集的實現。這意味着從一個TreeSet對象獲得第一個迭代器將按升序提供對象。TreeSet類使用了一個TreeMap。

爲優化hashset空間的使用,可以調優初始容量和負載因子。TreeSet 不包含調優選項,因爲樹總是平衡的,保證了插入、刪除、查詢的性能的高效。

當您要從集合中以有序的方式抽取元素時,TreeSet實現會有用處。爲了能順利進行,添加到TreeSet的元素必須是可排序的。 

import java.util.*;
public class SetExample {
      public static void main(String args[]) {
          Set set = new HashSet();
          set.add("Bernadine");
          set.add("Elizabeth");
          set.add("Gene");
          set.add("Elizabeth");
          set.add("Clara");
          System.out.println(set);
 
          Set sortedSet = new TreeSet(set);
          System.out.println(sortedSet);
      }
}

五、List

List接口繼承了Collection接口,定義一個允許重複項的有序集合。該接口不但能夠對列表的一部分進行處理,還添加了面向位置的操作。

實際上有兩種list:一種是基本的ArrayList,其優點在於隨機訪問元素,另一種是更強大的LinkedList,它並不是快速隨機訪問設計的,而是具有更通用的方法。

  • List : 次序是List最重要的特點:它保證維護元素特定的順序。
  • ArrayList : 由數組實現的List。允許對元素進行快速隨機訪問,但是向List中間插入與移除元素的速度很慢。
  • LinkedList : 對順序訪問進行了優化,向List中間插入與刪除的開銷並不大,隨機訪問則相對較慢。還具有下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 這些方法 (沒有在任何接口或基類中定義過)使得LinkedList可以當作堆棧、隊列和雙向隊列使用。
  • Vector:實現一個類似數組一樣的表,自動增加容量來容納你所需的元素。使用下標存儲和檢索對象就象在一個標準的數組中一樣。你也可以用一個迭代器從一個Vector中檢索對象Vector是唯一的同步容器類!!
  • stack:這個類從vector派生而來,並增加了方法實現棧,一種後進先出的存儲結構。

List的用法示例:

package collection;
 
import java.util.*;
 
public class SetExample {
    public static void main(String[] args) {
        List linkedList = new LinkedList();
        for (int i = 0; i <= 5; i++) {
            linkedList.add("a"+i);
        }
        System.out.println(linkedList);
        linkedList.add(3,"a100");
        System.out.println(linkedList);
        linkedList.set(6,"a200");
        System.out.println(linkedList);
        System.out.println(linkedList.get(2));
        System.out.println(linkedList.indexOf("a3"));
        linkedList.remove(1);
        System.out.println(linkedList);
    }
}

六、list和set對比

Set子接口:無序,不允許重複,檢索元素效率低下,刪除和插入效率高,插入和刪除不會引起元素位置改變。
List子接口:有序,可以有重複元素,和數組類似,List可以動態增長,查找元素效率高,插入刪除元素效率低,因爲會引起其他元素位置改變。

Set和List具體子類:
    Set
     |————HashSet:以哈希表的形式存放元素,插入刪除速度很快。

    List
     |————ArrayList:動態數組
     |————LinkedList:鏈表、隊列、堆棧。

七、map

1、map接口不是Collection接口的繼承。

不重複的鍵到值的映射。

2、Map.Entry 接口

map的entrySet()方法返回一個實現map.entry接口的對象集合。集合中每個對象都是底層map中一個特定的鍵值對。

3、HashMap 類和 TreeMap 類

在map中插入、刪除和定位元素,HashMap是最好的選擇。但如果您要按順序遍歷鍵,那麼TreeMap 會更好。根據集合大小,先把元素添加HashMap,再把這種映射轉換成一個用於有序鍵遍歷的TreeMap 可能更快。

爲了優化hashmap空間的使用,您可以調優初始容量和負載因子。這個treeMap沒有調優選項,因爲該樹總處於平衡狀態。

  • hashtable:實現一個映象,所有的鍵必須非空。爲了能高效的工作,定義鍵的類必須實現hashcode()方法和equal()方法。這個類時前面Java實現的一個繼承,並且通常能在實現映象的其它類中更好地使用。
  • hashmap:實現一個映象,運行存儲空對象,而且允許鍵是空(由於鍵必須是唯一的,當然只能有一個空)。
  • WeakHashMap:如果有一個鍵對於一個對象而言不再被引用,鍵將被捨棄,WeakHashMap在具有大量數據時使用。
  • TreeMap: 實現這樣一個映象,對象是按鍵升序排列的。

4、map的使用示例

以下程序演示了具體map類的使用。該程序對自命令行傳遞的詞進行頻率計數。hashmap起初用於數據存儲。後來,映射被轉換爲TreeMap以顯示有序的鍵列列表。

package collection;
 
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
 
public class MapExample {
    public static void main(String[] args) {
        String[] array = {"a","b","c","d","e"};
        Map map = new HashMap();
        Integer ONE = new Integer(1);
        for (int i=0, n=array.length; i<n; i++) {
            String key = array[i];
            int frequency = i+1;
            map.put(key, frequency);
        }
        System.out.println(map);
        Map sortedMap = new TreeMap(map);
        System.out.println(sortedMap);
        //hashmap的同步
        Map map1 = Collections.synchronizedMap(map);
        System.out.println(map1);
    }
}

5、控制檯輸出

八、解惑

1、什麼是iterator

對集合的遍歷,遍歷的時候不建議修改集合。

2、Iterator與ListIterator有什麼區別?

Iterator:只能正向遍歷集合

ListIerator:繼承Iterator,可以雙向列表遍歷

3、HashMap與HashTable有什麼區別?

HashMap允許空值作爲鍵或值,不同步的,迭代時採用的是快速失敗機制

HashTable不允許空值,同步的

注:有多線程的可能時,使用hashtable,反之使用hashmap。非線程安全的數據結構能帶來更好地性能。

如果將來有可能需要按順序獲取鍵值對,hashmap是更好地選擇,因爲hashmap的一個子類LinkedHashMap。

如果多線程時使用hashmap,Collections.synchronizedMap()可以代替,總的來說HashMap更靈活。

4、在Hashtable上下文中同步是什麼意思?

同步意味着在一個時間點只能有一個線程可以改變哈希表,任何線程在執行hashtable的更新操作前需要獲取對象鎖,其它線程等待鎖的釋放。

5、爲什麼Vector不推薦使用?

使用時ArrayList優先於Vector,Vector是同步的,性能會低一些,如果迭代一個vector,還要加鎖,以避免其他線程同一時刻改變集合,加鎖效率更慢。

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