前言:java
數組Array和集合的區別:數組
一、數組是大小固定的,而且同一個數組只能存放類型同樣的數據(基本類型/引用類型)安全
二、JAVA集合能夠存儲和操做數目不固定的一組數據。數據結構
三、若程序時不知道究竟須要多少對象,須要在空間不足時自動擴增容量,則須要使用容器類庫,array不適用。 多線程
注:使用相應的toArray()和Arrays.asList()方法能夠相互轉換。性能
集合:優化
集合類存放於Java.util包中。spa
集合類存放的都是對象的引用,而非對象自己,出於表達上的便利,咱們稱集合中的對象就是指集合中對象的引用。.net
集合類型主要有三種:set(集)、list(列表)、map(映射)。命令行
1、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。
2、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); } }
[Gene, Clara, Bernadine, Elizabeth] [Bernadine, Clara, Elizabeth, Gene]
3、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); } }
4、list和set對比
Set子接口:無序,不容許重複,檢索元素效率低下,刪除和插入效率高,插入和刪除不會引發元素位置改變。
List子接口:有序,能夠有重複元素,和數組相似,List能夠動態增加,查找元素效率高,插入刪除元素效率低,由於會引發其餘元素位置改變。
Set和List具體子類:
Set
|————HashSet:以哈希表的形式存放元素,插入刪除速度很快。
List
|————ArrayList:動態數組
|————LinkedList:鏈表、隊列、堆棧。
5、map
map接口不是Collection接口的繼承。
不重複的鍵到值的映射。
Map.Entry 接口
map的entrySet()方法返回一個實現map.entry接口的對象集合。集合中每一個對象都是底層map中一個特定的鍵值對。
HashMap 類和 TreeMap 類
在map中插入、刪除和定位元素,HashMap是最好的選擇。但若是您要按順序遍歷鍵,那麼TreeMap 會更好。根據集合大小,先把元素添加HashMap,再把這種映射轉換成一個用於有序鍵遍歷的TreeMap 可能更快。
爲了優化hashmap空間的使用,您能夠調優初始容量和負載因子。這個treeMap沒有調優選項,由於該樹總處於平衡狀態。
hashtable:實現一個映象,全部的鍵必須非空。爲了能高效的工做,定義鍵的類必須實現hashcode()方法和equal()方法。這個類時前面Java實現的一個繼承,而且一般能在實現映象的其它類中更好地使用。
hashmap:實現一個映象,運行存儲空對象,並且容許鍵是空(因爲鍵必須是惟一的,固然只能有一個空)。
WeakHashMap:若是有一個鍵對於一個對象而言再也不被引用,鍵將被捨棄,WeakHashMap在具備大量數據時使用。
TreeMap: 實現這樣一個映象,對象是按鍵升序排列的。
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); } }
結果:
6、解惑:
一、什麼是iterator
對集合的遍歷,遍歷的時候不建議修改集合。
二、Iterator與ListIterator有什麼區別?
Iterator:只能正向遍歷集合
ListIerator:繼承Iterator,能夠雙向列表遍歷
三、HashMap與HashTable有什麼區別?
HashMap容許空值做爲鍵或值,不一樣步的,迭代時採用的是快速失敗機制
HashTable不容許空值,同步的
注:有多線程的可能時,使用hashtable,反之使用hashmap。非線程安全的數據結構能帶來更好地性能。
若是未來有可能須要按順序獲取鍵值對,hashmap是更好地選擇,由於hashmap的一個子類LinkedHashMap。
若是多線程時使用hashmap,Collections.synchronizedMap()能夠代替,總的來講HashMap更靈活。
四、在Hashtable上下文中同步是什麼意思?
同步意味着在一個時間點只能有一個線程能夠改變哈希表,任何線程在執行hashtable的更新操做前須要獲取對象鎖,其它線程等待鎖的釋放。
五、爲何Vector不推薦使用?
使用時ArrayList優先於Vector,Vector是同步的,性能會低一些,若是迭代一個vector,還要加鎖,以免其餘線程同一時刻改變集合,加鎖效率更慢。