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