集合
Java的集合大致可以分成Set List 和 Map三種體系結(jié)構(gòu)。其中Set代表無序不可重復(fù)的集合;List代表有序、重復(fù)的集合;而Map代表具有映射關(guān)系的集合。
Java的集合類主要由兩個(gè)接口派生而來:Collection 和 Map,這兩個(gè)接口是根接口。Set 和 List兩個(gè)接口派生于Collection接口。根據(jù)Set List 和 Map三種類型的特點(diǎn),可以得出這樣的結(jié)論:
如果訪問List集合中的元素,可以直接使用元素的索引;如果訪問Map集合需要根據(jù)key來訪問,訪問Set集合則只能根據(jù)元素本身。使用比較多的是: HashSet TreeSet ArrayList ArrayDeque LinkedList HashMap TreeMap
Set
Set集合不允許包含相同的元素,如果把兩個(gè)相同的元素添加到Set集合中,則會(huì)添加失敗。Set判斷兩個(gè)對(duì)象相同不是使用==運(yùn)算符,而是根據(jù)equals方法,也就是說兩個(gè)對(duì)象用equlas方法判斷返回false,則可以添加成功。Set的子類包含:HashSet 、 TreeSet 、 EnumSet
HashSet
HashSet具有以下幾個(gè)特點(diǎn):
不能保證元素的排列順序,遍歷的元素可能與添加的元素順序可能不一樣。
HashSet不是同步的,如果兩個(gè)以上的線程來修改HashSet則需要手動(dòng)的保證代碼的同步。
集合元素可以為null
HashSet中存入一個(gè)元素的時(shí)候,系統(tǒng)會(huì)根據(jù)該元素的hashCode()返回的數(shù)字決定存儲(chǔ)的位置。如果兩個(gè)元素根據(jù)equals方法返回true,但是hashCode不一樣,則HashSet同樣會(huì)將兩個(gè)對(duì)象添加成功。
因此HashSet判斷兩個(gè)對(duì)象是否相等,需要equals返回true,同時(shí)hashCode返回的數(shù)值也一樣。應(yīng)該在重寫equlas方法的時(shí)候,應(yīng)該也需要重寫hashCode方法。
LinkedHashSet
LinkedHashSet 是HashSet的子類,它也是根據(jù)hashCode值來決定元素的存儲(chǔ)位置,但是它不同的是需要使用鏈表來維護(hù)元素的次序。這樣使得元素看起來是以插入的順序保存的。
TreeSet
TreeSet是SortedSet接口的實(shí)現(xiàn)類,因此它可以確保TreeSet中的元素都是有序的。
TreeSet集合采用hash算法來決定元素的存儲(chǔ)位置,同時(shí)TreeSet采用紅黑樹的數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)集合元素。TreeSet采用了兩種排序方法:自然排序和定制排序。
自然排序是根據(jù)添加到TreeSet中的對(duì)象的compareTo(Object obj)來判斷。因此在加入到TreeSet中的所有對(duì)象都要實(shí)現(xiàn)Comparable接口。
class Test implements Comparable {
...
public int comparaTo(Object obj) {
...
}
...
}
這個(gè)Test對(duì)象就可以添加到TreeSet集合中。
定制排序:
定制排序是創(chuàng)建TreeSet對(duì)象的時(shí)候指定比較方法,
TreeSet ts = new TreeSet(new Comparator() {
public int compare(Object o1, Object o2) {
...
}
});
這樣在添加到TreeSet中的對(duì)象就不需要自己實(shí)現(xiàn)Comparable接口,因?yàn)門reeSet已經(jīng)幫你實(shí)現(xiàn)了。
ArrayList Vector
ArrayList && Vector 都是基于數(shù)組實(shí)現(xiàn)的List類。他們都是內(nèi)部封裝了一個(gè)動(dòng)態(tài)可分配的數(shù)組,使用initialCapacity參數(shù)來設(shè)置該數(shù)組的長度,當(dāng)向ArrayList和Vector中添加的元素超過了數(shù)組的長度則initialCapacity將會(huì)自動(dòng)增長。
ArrayList 與 Vector之間的主要區(qū)別是:ArrayList是線程不安全的,當(dāng)多個(gè)線程修改同一個(gè)ArrayList集合的時(shí)候,需要手動(dòng)的保證線程的安全。Vector是線程安全的。
在Arrays中提供了asList(….)方法,把指定的數(shù)組轉(zhuǎn)成List集合。但是需要注意的是轉(zhuǎn)成后的List對(duì)象是不可以使用add remove等操作的,只能遍歷。
LinkedList
LinkedList 是List的一個(gè)集合,同時(shí)還實(shí)現(xiàn)了Deque接口,因此它可以被當(dāng)成雙端隊(duì)列來使用。自然也可以被當(dāng)成棧來使用。LinkedList內(nèi)部使用的是鏈表的形式來保存集合中的元素。因此隨機(jī)訪問的性能不好,但是插入和刪除的性能比較好。
-Xms 是設(shè)置JVM的堆內(nèi)存初始值大小。 -Xmx 是設(shè)置JVM的堆內(nèi)存最大大小。
總結(jié):如果需要隨機(jī)訪問的性能,則考慮使用ArrayList,如果需要插入、刪除的性能,則需要考慮使用LinkedList.
Hashtable && HashMap
兩者之間的區(qū)別:
- Hashtable 是一個(gè)線程安全的類,HashMap線程不安全。
- Hashtable 不允許使用null作為key和value,但是HashMap是可以使用null作為key和value的。
因此 HashMap中只能有一個(gè)key位null,但是可以有無數(shù)的value值為null。
與LinkedHashSet一樣,Map中也存在一個(gè)LinkedHashMap,用鏈表來記錄map對(duì)象的添加順序。
SortedMap 與 TreeMap 也是可以排序的:
- 自然排序: TreeMap 的所有key必須實(shí)現(xiàn)Comparable接口,而且所有的key應(yīng)該是同一個(gè)類的對(duì)象,否則會(huì)拋出異常信息。
- 定制排序: 創(chuàng)建TreeMap對(duì)象的時(shí)候,傳入一個(gè)Comparator對(duì)象,該對(duì)象負(fù)責(zé)對(duì)TreeMap中所有的key進(jìn)行排序。
Collections
Java 為 Set List Map 提供了一個(gè)工具類: Collections,它提供了大量方法對(duì)集合元素進(jìn)行排序,查詢和修改等操作。還提供了將集合元素對(duì)象設(shè)置為不可變、對(duì)集合對(duì)象實(shí)現(xiàn)同步的控制方法。
reverse / shuffle / sort / swap / rotate
Collections 提供了多個(gè)synchronizedXxx()方法,將集合包裝成線程同步的集合。從而解決多線程并發(fā)的問題。
Collection c = Collecionts.synchronizedCollection(new ArrayList());
List list = Collecionts.synchronizedList(new ArrayList());
Set set = Collecionts.synchronizedSet(new HashSet());
Map m = Collecionts.synchronizedMap(new HashMap());