java集合 java
紅色部分:集合與數組間轉換操做的方法:以下圖 面試
在調用it.next()方法以前必需要調用it.hasNext()進行檢測。若不調用,且下一條記錄無效,直接調用it.next()會拋出NoSuchElementException異常 算法
while(it.hasNext()){ 設計模式
…..it.next(); 數組
} 安全
使用 foreach 循環遍歷集合元素 數據結構
一、ListIterator和Iterator都有hasNext()和next()方法,能夠實現順序向後遍歷。可是ListIterator有hasPrevious()和previous()方法,能夠實現逆向(順序向前)遍歷。Iterator就不能夠。 多線程
二、ListIterator能夠定位當前的索引位置,nextIndex()和previousIndex()能夠實現。Iterator 沒有此功能。 併發
三、ListIterator有add()方法,能夠向List中插入對象,而Iterator不能。 框架
四、均可實現刪除對象,可是ListIterator能夠實現對象的修改,set()方法能夠實現。Iterator僅能遍歷,不能修改。由於ListIterator的這些功能,能夠實現對LinkedList等List數據結構的操做。
hashCode() 方法
對象中用做 equals() 方法比較的 Field,都應該用來計算 hashCode 值
排 序——天然排序 Comparable 接口
排 序——定製排序 comparator接口
若使用自定義類做爲TreeMap的key,所屬類須要重寫equals()和hashCode()方法,且equals()方法返回true時,compareTo()方法應返回0
Properties pros = new Properties(); pros.load(new FileInputStream("jdbc.properties")); String user = pros.getProperty("user"); System.out.println(user); |
查找、替換
同步控制
Enumeration stringEnum = new StringTokenizer("a-b*c-d-e-g", "-"); while(stringEnum.hasMoreElements()){ Object obj = stringEnum.nextElement(); System.out.println(obj); } |
1 Collection 和 Collections的區別
答:Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.
Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做
--------------------------------------------------
2 Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==仍是equals()? 它們有何區別
答:Set裏的元素是不能重複的,那麼用iterator()方法來區分重複與否。equals()是判讀兩個Set是否相等
equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,爲的是當兩個分離的對象的內容
和類型相配的話,返回真值
--------------------------------------------------
3 List, Set, Map是否繼承自Collection接口
答: List,Set是,Map不是
--------------------------------------------------
4 兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不對
答:不對,有相同的hash code
--------------------------------------------------
5 說出ArrayList,Vector, LinkedList的存儲性能和特性
答:ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector因爲使用了synchronized方法(線程安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。
--------------------------------------------------
6 HashMap和Hashtable的區別
答:HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完成了Map接口,主要區別在於
HashMap容許空(null)鍵值(key),因爲非線程安全,效率上可能高於Hashtable。
HashMap容許將null做爲一個entry的key或者value,而Hashtable不容許。
HashMap把Hashtable的contains方法去掉了,改爲containsvalue和containsKey。由於contains方法容易讓人引發誤解。
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。
最大的不一樣是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不須要本身爲它的方法實現同步,而HashMap 就必須爲之提供外同步。
Hashtable和HashMap採用的hash/rehash算法都大概同樣,因此性能不會有很大的差別。
--------------------------------------------------
7 ArrayList和Vector的區別,HashMap和Hashtable的區別
答:就ArrayList與Vector主要從二方面來講.
一.同步性:Vector是線程安全的,也就是說是同步的,而ArrayList是線程序不安全的,不是同步的
二.數據增加:當須要增加時,Vector默認增加爲原來一培,而ArrayList倒是原來的一半
就HashMap與HashTable主要從三方面來講。
一.歷史緣由:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現
二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的
三.值:只有HashMap可讓你將空值做爲一個表的條目的key或value
如何檢查一個未排序的數組中是否包含某個特定值,這是一個在Java中很是實用而且頻繁使用的操做。檢查數組中是否包含特定值能夠用多種不一樣的方式實現,可是時間複雜度差異很大。下面,將爲你們展現各類方法及其須要花費的時間。
1.檢查數組中是否包含特定值的四種不一樣方法
1)使用List:
public static boolean useList(String[] arr, String targetValue) { return Arrays.asList(arr).contains(targetValue); } |
2)使用Set:
1 2 3 4 |
public static boolean useSet(String[] arr, String targetValue) { Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue); } |
3)使用一個簡單循環:
1 2 3 4 5 6 7 |
public static boolean useLoop(String[] arr, String targetValue) { for(String s: arr){ if(s.equals(targetValue)) return true; } return false; } |
4)使用Arrays.binarySearch():
注:下面的代碼是錯誤的,這樣寫出來僅僅爲了理解方便。binarySearch()只能用於已排好序的數組中。因此,你會發現下面結果很奇怪。
1 2 3 4 5 6 7 |
public static boolean useArraysBinarySearch(String[] arr, String targetValue) { int a = Arrays.binarySearch(arr, targetValue); if(a > 0) return true; else return false; } |
2.時間複雜度
經過下面的這段代碼能夠近似比較幾個方法的時間複雜度。雖然分別搜索一個大小爲5、1K、10K的數組是不夠精確的,可是思路是清晰的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public static void main(String[] args) { String[] arr = new String[] { "CD", "BC", "EF", "DE", "AB"};
//use list long startTime = System.nanoTime(); for (int i = 0; i < 100000; i++) { useList(arr, "A"); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println("useList: " + duration / 1000000);
//use set startTime = System.nanoTime(); for (int i = 0; i < 100000; i++) { useSet(arr, "A"); } endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("useSet: " + duration / 1000000);
//use loop startTime = System.nanoTime(); for (int i = 0; i < 100000; i++) { useLoop(arr, "A"); } endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("useLoop: " + duration / 1000000);
//use Arrays.binarySearch() startTime = System.nanoTime(); for (int i = 0; i < 100000; i++) { useArraysBinarySearch(arr, "A"); } endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("useArrayBinary: " + duration / 1000000); } |
結果:
1 2 3 4 |
useList: 13 useSet: 72 useLoop: 5 useArraysBinarySearch: 9 |
對於長度爲1K的數組:
1 2 3 4 5 6 |
String[] arr = new String[1000];
Random s = new Random(); for(int i=0; i< 1000; i++){ arr[i] = String.valueOf(s.nextInt()); } |
結果:
1 2 3 4 |
useList: 112 useSet: 2055 useLoop: 99 useArrayBinary: 12 |
對於長度爲10K的數組:
1 2 3 4 5 6 |
String[] arr = new String[10000];
Random s = new Random(); for(int i=0; i< 10000; i++){ arr[i] = String.valueOf(s.nextInt()); } |
結果:
1 2 3 4 |
useList: 1590 useSet: 23819 useLoop: 1526 useArrayBinary: 12 |
很明顯,使用簡單循環的方法比使用其餘任何集合效率更高。許多開發者會使用第一種方法,可是它並非高效的。將數組壓入Collection類型中,須要首先將數組元素遍歷一遍,而後再使用集合類作其餘操做。
若是使用Arrays.binarySearch()方法,數組必須是已排序的。因爲上面的數組並無進行排序,因此該方法不可以使用。
實際上,若是你須要藉助數組或者集合類高效地檢查數組中是否包含特定值,一個已排序的列表或樹能夠作到時間複雜度爲O(log(n)),hashset能夠達到O(1)。