淺談Java中經常使用數據構造的完成類 Collection和Map。本站提示廣大學習愛好者:(淺談Java中經常使用數據構造的完成類 Collection和Map)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談Java中經常使用數據構造的完成類 Collection和Map正文
線性表,鏈表,哈希表是經常使用的數據構造,在停止Java開辟時,JDK曾經為我們供給了一系列響應的類來完成根本的數據構造。這些類均在java.util包中。本文試圖經由過程簡略的描寫,向讀者論述各個類的感化和若何准確應用這些類。
Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └WeakHashMap
Collection接口
Collection是最根本的聚集接口,一個Collection代表一組Object,即Collection的元素(Elements)。一些Collection許可雷同的元素而另外一些不可。一些能排序而另外一些不可。Java SDK不供給直接繼續自Collection的類,Java SDK供給的類都是繼續自Collection的“子接口”如List和Set。
一切完成Collection接口的類都必需供給兩個尺度的結構函數:無參數的結構函數用於創立一個空的Collection,有一個Collection參數的結構函數用於創立一個新的Collection,這個新的Collection與傳入的Collection有雷同的元素。後一個結構函數許可用戶復制一個Collection。
若何遍歷Collection中的每個元素?豈論Collection的現實類型若何,它都支撐一個iterator()的辦法,該辦法前往一個迭代子,應用該迭代子便可一一拜訪Collection中每個元素。
典范的用法以下:
Iterator it = collection.iterator(); // 取得一個迭代子 while(it.hasNext()) { Object obj = it.next(); // 獲得下一個元素 }
由Collection接口派生的兩個接口是List和Set。
List接口
List是有序的Collection,應用此接口可以或許准確的掌握每一個元素拔出的地位。用戶可以或許應用索引(元素在List中的地位,相似於數組下標)來拜訪List中的元素,這相似於Java的數組。
和上面要提到的Set分歧,List許可有雷同的元素。
除具有Collection接口必備的iterator()辦法外,List還供給一個listIterator()辦法,前往一個ListIterator接口,和尺度的Iterator接口比擬,ListIterator多了一些add()之類的辦法,許可添加,刪除,設定元素,還能向前或向後遍歷。
完成List接口的經常使用類有LinkedList,ArrayList,Vector和Stack。
LinkedList類
LinkedList完成了List接口,許可null元素。另外LinkedList供給額定的get,remove,insert辦法在LinkedList的首部或尾部。這些操作使LinkedList可被用作客棧(stack),隊列(queue)或雙向隊列(deque)。
留意LinkedList沒有同步辦法。假如多個線程同時拜訪一個List,則必需本身完成拜訪同步。一種處理辦法是在創立List時結構一個同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
ArrayList類
ArrayList完成了可變年夜小的數組。它許可一切元素,包含null。ArrayList沒有同步。
size,isEmpty,get,set辦法運轉時光為常數。然則add辦法開支為分攤的常數,添加n個元素須要O(n)的時光。其他的辦法運轉時光為線性。
每一個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的年夜小。這個容量可跟著赓續添加新元素而主動增長,然則增加算法並沒有界說。當須要拔出年夜量元素時,在拔出前可以挪用ensureCapacity辦法來增長ArrayList的容量以進步拔出效力。
和LinkedList一樣,ArrayList也長短同步的(unsynchronized)。
Vector類
Vector異常相似ArrayList,然則Vector是同步的。由Vector創立的Iterator,固然和ArrayList創立的Iterator是統一接口,然則,由於Vector是同步的,當一個Iterator被創立並且正在被應用,另外一個線程轉變了Vector的狀況(例如,添加或刪除一些元素),這時候挪用Iterator的辦法時將拋出ConcurrentModificationException,是以必需捕捉該異常。
Stack 類
Stack繼續自Vector,完成一個落後先出的客棧。Stack供給5個額定的辦法使得Vector得以被看成客棧應用。根本的push和pop辦法,還有peek辦法獲得棧頂的元素,empty辦法測試客棧能否為空,search辦法檢測一個元素在客棧中的地位。Stack剛創立後是空棧。
Set接口
Set是一種不包括反復的元素的Collection,即隨意率性的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。
很顯著,Set的結構函數有一個束縛前提,傳入的Collection參數不克不及包括反復的元素。
請留意:必需當心操作可變對象(Mutable Object)。假如一個Set中的可變元素轉變了本身狀況招致Object.equals(Object)=true將招致一些成績。
Map接口
請留意,Map沒有繼續Collection接口,Map供給key到value的映照。一個Map中不克不及包括雷同的key,每一個key只能映照一個value。Map接口供給3種聚集的視圖,Map的內容可以被看成一組key聚集,一組value聚集,或許一組key-value映照。
Hashtable類
Hashtable完成Map接口,完成一個key-value映照的哈希表。任何非空(non-null)的對象都可作為key或許value。
添加數據應用put(key, value),掏出數據應用get(key),這兩個根本操作的時光開支為常數。
Hashtable經由過程initial capacity和load factor兩個參數調劑機能。平日缺省的load factor 0.75較好地完成了時光和空間的平衡。增年夜load factor可以節儉空間但響應的查找時光將增年夜,這會影響像get和put如許的操作。
應用Hashtable的簡略示例以下,將1,2,3放到Hashtable中,他們的key分離是”one”,”two”,”three”:
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要掏出一個數,好比2,用響應的key:
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
因為作為key的對象將經由過程盤算其散列函數來肯定與之對應的value的地位,是以任何作為key的對象都必需完成hashCode和equals辦法。hashCode和equals辦法繼續自根類Object,假如你用自界說的類看成key的話,要相當當心,依照散列函數的界說,假如兩個對象雷同,即obj1.equals(obj2)=true,則它們的hashCode必需雷同,但假如兩個對象分歧,則它們的hashCode紛歧定分歧,假如兩個分歧對象的hashCode雷同,這類景象稱為抵觸,抵觸會招致操作哈希表的時光開支增年夜,所以盡可能界說好的hashCode()辦法,能加速哈希表的操作。
假如雷同的對象有分歧的hashCode,對哈希表的操作會湧現意想不到的成果(等待的get辦法前往null),要防止這類成績,只須要切記一條:要同時復寫equals辦法和hashCode辦法,而不要只寫個中一個。
Hashtable是同步的。
HashMap類
HashMap和Hashtable相似,分歧的地方在於HashMap長短同步的,而且許可null,即null value和null key。,然則將HashMap視為Collection時(values()辦法可前往Collection),其迭代子操作時光開支和HashMap的容量成比例。是以,假如迭代操作的機能相當主要的話,不要將HashMap的初始化容量設得太高,或許load factor太低。
WeakHashMap類
WeakHashMap是一種改良的HashMap,它對key實施“弱援用”,假如一個key不再被內部所援用,那末該key可以被GC收受接管。
總結
假如觸及到客棧,隊列等操作,應當斟酌用List,關於須要疾速拔出,刪除元素,應當應用LinkedList,假如須要疾速隨機拜訪元素,應當應用ArrayList。
Java.util.Collections類包
java.util.Collections類包括許多有效的辦法,可使法式員的任務變得加倍輕易,然則這些辦法平日都沒有被充足天時用。Javadoc給出Collections類最完全的描寫:“這一個類包括可以操作或前往聚集的公用靜態類。
” 1.2 所含辦法
Iterator, ArrayList, Elements, Buffer, Map,Collections
列子:
import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; public class CollectionsSort { public CollectionsSort() { } public static void main(String[] args) { double array[] = {111, 111, 23, 456, 231 }; List list = new ArrayList(); List li = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); //list.add(""+array[i]); } double arr[] = {111}; for(int j=0;j<arr.length;j++){ li.add(new Double(arr[j])); } }
2. 詳細操作
1) 排序(Sort)
應用sort辦法可以依據元素的天然次序對指定列表按升序停止排序。列表中的一切元素都必需完成 Comparable 接口。此列表內的一切元素都必需是應用指定比擬器可互相比擬的
double array[] = {112, 111, 23, 456, 231 }; for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.sort(list); for (int i = 0; i < array.length; i++) { System.out.println(li.get(i)); } //成果:112,111,23,456,231
2) 混排(Shuffling)
混排算法所做的正好與 sort 相反: 它打亂在一個 List 中能夠有的任何分列的蹤影。也就是說,基於隨機源的輸出重排該 List, 如許的分列具有雷同的能夠性(假定隨機源是公平的)。這個算法在完成一個試試看的游戲中長短常有效的。例如,它可被用來混排代表一副牌的 Card 對象的一個 List 。別的,在生成測試案例時,它也是非常有效的。
Collections.Shuffling(list) double array[] = {112, 111, 23, 456, 231 }; for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.shuffle(list); for (int i = 0; i < array.length; i++) { System.out.println(li.get(i)); } //成果:112,111,23,456,231
3) 反轉(Reverse)
應用Reverse辦法可以依據元素的天然次序對指定列表按降序停止排序。
Collections.reverse(list) double array[] = {112, 111, 23, 456, 231 }; for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections. reverse (list); for (int i = 0; i < array.length; i++) { System.out.println(li.get(i)); } //成果:231,456,23,111,112 4) 調換所以的元素(Fill) 應用指定元素調換指定列表中的一切元素。 String str[] = {"dd","aa","bb","cc","ee"}; for(int j=0;j<str.length;j++){ li.add(new String(str[j])); } Collections.fill(li,"aaa"); for (int i = 0; i < li.size(); i++) { System.out.println("list[" + i + "]=" + li.get(i)); } //成果:aaa,aaa,aaa,aaa,aaa
5) 拷貝(Copy)
用兩個參數,一個目的 List 和一個源 List, 將源的元素拷貝到目的,並籠罩它的內容。目的 List 至多與源一樣長。假如它更長,則在目的 List 中的殘剩元素不受影響。
Collections.copy(list,li): 前面一個參數是目的列表 ,前一個是源列表
double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); List li = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } double arr[] = {1131,333}; String str[] = {"dd","aa","bb","cc","ee"}; for(int j=0;j<arr.length;j++){ li.add(new Double(arr[j])); } Collections.copy(list,li); for (int i = 0; i <list.size(); i++) { System.out.println("list[" + i + "]=" + list.get(i)); } //成果:1131,333,23,456,231
6) 前往Collections中最小元素(min)
依據指定比擬器發生的次序,前往給定 collection 的最小元素。collection 中的一切元素都必需是經由過程指定比擬器可互相比擬的
Collections.min(list) double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.min(list); for (int i = 0; i <list.size(); i++) { System.out.println("list[" + i + "]=" + list.get(i)); } //成果:23
7) 前往Collections中最小元素(max)
依據指定比擬器發生的次序,前往給定 collection 的最年夜元素。collection 中的一切元素都必需是經由過程指定比擬器可互相比擬的
Collections.max(list) double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.max(list); for (int i = 0; i <list.size(); i++) { System.out.println("list[" + i + "]=" + list.get(i)); } //成果:456
8) lastIndexOfSubList
前往指定源列表中最初一次湧現指定目的列表的肇端地位
int count = Collections.lastIndexOfSubList(list,li); double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); List li = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } double arr[] = {111}; String str[] = {"dd","aa","bb","cc","ee"}; for(int j=0;j<arr.length;j++){ li.add(new Double(arr[j])); } Int locations = Collections. lastIndexOfSubList (list,li); System.out.println(“===”+ locations); //成果 3
9) IndexOfSubList
前往指定源列表中第一次湧現指定目的列表的肇端地位
int count = Collections.indexOfSubList(list,li); double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); List li = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } double arr[] = {111}; String str[] = {"dd","aa","bb","cc","ee"}; for(int j=0;j<arr.length;j++){ li.add(new Double(arr[j])); } Int locations = Collections.indexOfSubList(list,li); System.out.println(“===”+ locations); //成果 1
10) Rotate
依據指定的間隔輪回挪動指定列表中的元素
Collections.rotate(list,-1);
假如是正數,則正向挪動,負數則偏向挪動
double array[] = {112, 111, 23, 456, 231 }; List list = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(new Double(array[i])); } Collections.rotate(list,-1); for (int i = 0; i <list.size(); i++) { System.out.println("list[" + i + "]=" + list.get(i)); } //成果:111,23,456,231,112
以上這篇淺談Java中經常使用數據構造的完成類 Collection和Map就是小編分享給年夜家的全體內容了,願望能給年夜家一個參考,也願望年夜家多多支撐。