項目中用到的集合不可謂很少,對於本身的一次面試,要求說下本身用過的集合,本身開始說的並不系統也不完整,一直耿耿於懷,特整理一下,以備後期之用和幫助後來者。html
package com.love.malinda.utils; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * 關於collection 及 map 等相關概念及經常使用方式 * 目的:將集合和map處所涉及的東西儘可能詳細的整理,理出邏輯圖 和 經常使用的方法 * * Date 2017-1-13 * @author Aaron * */ public class CollectionAndMapStudy { /* * 兩篇挺好的博文。 * -- http://www.oracle.com/technetwork/cn/articles/maps1-100947-zhs.html 比較官方的文檔。 * -- http://blog.csdn.net/speedme/article/details/22398395 --也是總結的比較詳細的一篇博文,而且裏面的經常使用方法都有涉及。 * * -- 參考的博文: -- 在下面的註釋中有說起。 * * 相關結構圖: * * Collection -->List --> Vector * Collection -->List --> Vector --> Stack * Collection -->List --> ArrayList * Collection -->List --> LinkedList * Collection -->Set -->HashSet * Collection -->Set -->HashSet -->LinkedHashSet * Collection -->Set -->SortedSet -->TreeSet * * Map -->SortedMap -->TreeMap * Map -->HashMap * * 相關概念性的介紹: * * Collection :最基本的集合接口。由Collection接口派生的兩個接口是List和Set。 * * List: 是有序的Collection。 * 使用此接口可以精確的控制元素插入的位置。 * 用戶可以使用索引來訪問list中的元素,相似 java 中的數組。 * List容許有相同的元素。 * * Vector: 基於 數組的list。 * 是線程同步的,這也是 其與 arraylist的一個重要區別。 * * Stack:繼承自 Vector,實現一個先進先出的堆棧。 * Stack提供5個額外的方法使得Vector得以被看成堆棧使用。 * 基本的push和pop 方法,還有peek方法獲得棧頂的元素,empty方法測試堆棧是否爲空,search方法檢測一個元素在堆棧中的位置。Stack剛建立後是空棧。 * * LinkedList:實現了List接口,容許null元素。 * 提供了額外的get、remove、insert方法在LinkedList的首部或尾部。這些操做使LinkedList可被用做堆棧(stack),隊列(queue)或者雙向隊列(deque) * 注意:LinkedList沒有同步方法。若是多個線程同時訪問一個List,則必須本身實現訪問同步。一種解決方式:在構建List時構造一個同步的List,List list = Collections.synchronizedList(new LinkedList(...)); * (上面這部分注意,須要詳細看看.....) * //在另外一篇博文中,對 LinkedList 的解釋 -- http://skyuck.iteye.com/blog/526358 * 不是基於數組的,因此不受數組性能限制。 * 它是同步的。 * 它的每一個節點Node都包含兩方面的內容:節點自己的數據信息 和 下一個節點的信息。因此當對 LinkedList作添加、刪除操做時候,就不用像基於數組的ArrayList同樣, * 必須進行大量的數據移動。而只須要更改nextNode的相關信息就能夠實現了,這是其優點。 * 適合添加、刪除等操做。 * * ArrayList:實現了可變大小的數組。能夠承載全部元素,包括 null。ArrayList 也不是同步的。 * 每一個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小。這個容量可隨着不斷添加新元素而自動增長,可是增加算法沒有定義。 * 當須要插入大量元素時候,能夠調用 ensureCapacity 方法來增長容量提升插入效率。 * 適合查詢。 補充:array 與 arraylist 區別:array大小是固定的,能夠包含基本類型和對象類型,可是必須是同類型元素; arraylist 大小是動態變化的,只能存儲對象類型,能夠是object;相比而言,提供了更多的方法和特性,好比 addAll()、removeAll()等,對於基本數據類型,集合使用自動裝箱來減小編碼的工做量。 * * ######## * * Set:不包含重複元素的Collection。Set最多有一個null元素。 * 實現的基礎 是 Map(HashMap)。 * * HashSet: List 基本上都是以Array爲基礎,可是Set是在hashMap的基礎上實現的,這是 set 和 list的根本區別。 * hashset的存儲方式是把 hashMap 中的key做爲Set的對應存儲項。 * 這種以hashmap方式的實現方式,由於 hashmap的key不能是重複的,這樣就使 set 不能有重複項。 * 無序的。 * * LinkedHashSet: HashSet 的一個子類,一個鏈表。 * * SortedSet: * * TreeSet:SortedSet 的子類。是有序的。 * * ############# * * Map:是一種把鍵對象和值對象進行關聯的容器,而一個值對象又能夠是一個Map,依次類推,這樣就可造成一個多級映射。(key-value形式)。 * key值不容許重複。 * * HashTable:實現k-v映射的哈希表。任何非空(non-null)的對象均可以做爲 key 或者 value。 * 其是同步的。 * * HashMap:與 HashTable 相似。 * 不一樣之處:HashMap 是非同步的,而且容許爲null。 * * * 幾個經常使用類的區別: * ArrayList:元素單個,效率高,多用於查詢;通常狀況,性能比較好,優先考慮。 * Vector:元素單個,線程安全,多用於查詢;若是在多線程條件下,能夠考慮。 * LinkedList:元素單個,多用於插入和刪除;比較頻繁的插入和刪除時候,能夠考慮。 * HashMap:元素成對,元素可爲空; * HashTable:元素成對,線程安全,元素不可爲空; * * 通常狀況下,ArrayList 的性能是最好的,可是若是集合內的元素須要頻繁的插入、刪除操做時候, LinkedList會比較好些。但但可是,ArrayList、Vector、LinkedList與數組相比,數組的效果更好。 * 若是在(元素類型固定,數組長度固定)的狀況下,儘可能使用數組來代替List。 * * * -- 來自 http://blog.csdn.net/softwave/article/details/4166598 的總結和補充: * * 1. Vector 是同步的,線程安全的。ArrayList 是異步的,其中的對象不是線程安全的。 * * 2. 關於數據增加方式: * ArrayList 和 Vector 都是使用數組來控制集合中的對象。二者在須要存儲的元素數目超過了當前內部數組的長度時候,會自動擴容。 Vector 自動增長原數組長度一倍,ArrayList 則爲 50%。 * * 3. 使用模式 * ArrayList 和 Vector 根據索引(下標)查找數據 或者 在末尾增長、刪除一個元素的時間花銷是同樣的。 * LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行向前或向後遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入數度較快! * * 4. 本身的一點點感觸: * 1. 上面的這些總結只是來自兩篇介紹的比較詳細的博文中,不免會有疏漏。若是遇到跟本身所學所知所用不一致的地方,最好的打開姿式是 針對某一項進行鍼對性的學習和理解。 * * 2. 在項目中常用集合、Map等的操做,可是在一次面試中,讓我列舉下本身使用過的集合,我卻說的一塌糊塗:總體知道一些,項目中只是傻瓜似的去用,根本沒有考慮其餘。 * 在述說時候,甚至有些漏掉了,通常性的介紹都是說的不全面,漏洞百出。因此想系統的整理學習下,雖然參閱網上的博文,有了一些好的瞭解,可是仍是感受這些博文介紹的 * 很模糊。還須要我本身手敲代碼嘗試下。學無止境,加油吧! * * * 下面的方法中,考慮的是將本身不熟悉的地方,整理下,如,map的相關操做。 * */ /** * 模擬獲取map數據用於遍歷 * @return */ public static Map<String, String> getMapData() { Map<String, String> map = new HashMap<String, String>(); for (int i = 0; i < 3; i++) { map.put("username"+i, "xiaoming"+i); map.put("password"+i, "mima"+i); } return map; } /** * map遍歷的幾種姿式 */ public void mapIteratorTest(){ Map<String, String> map = CollectionAndMapStudy.getMapData(); System.out.println("map的size():"+map.size()); /* * map遍歷的原理介紹:要明白其操做原理是怎麼進行的。 * 方式1:Set<k> keyset: 將map中全部的鍵存入到set集合(即將全部的key值存入到set中), 由於Set具有迭代器,能夠進行迭代遍歷。 * 全部能夠迭代方式取出全部的鏈,再根據get方法。獲取每個鍵對應的值。 * 總而言之,就是先獲取全部 key 的集合,而後遍歷key值,對應的就能取到該 key 對應的 value。 * * 方式2:Map 集合的取出原理: 將map集合轉成set集合。 再經過迭代器取出。 * set<Map.Entry<k,v>> entrySet: 將map集合中的映射關係(即鍵值對的方式存入到set中)存入到set集合中,而這個關係的數據類型就是:map.entry 。 * 總而言之,就是 將 map 及其中的 映射關係 轉換成 對應的 set 集合形式,再進行遍歷操做。 */ //1. // Set<Map.Entry<String, String>> entrySet = map.entrySet(); //在 for 循環中實際是 這樣對應的。獲取了set 集合,進行遍歷的。 for(Map.Entry<String, String> entry : map.entrySet()){ String key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"-----"+value); } //2.//將Map集合中的映射鍵值對取出。存入到Set集合 // 使用迭代器。注意迭代器的用法。 Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while(it.hasNext()){ Map.Entry<String, String> entry = it.next(); String key = entry.getKey(); String value = entry.getValue(); System.out.println(key+"===="+value); } //3.只能單獨遍歷 key 和 value for(String value : map.values()){ //只遍歷 value System.out.println("value :"+value); } for(String key : map.keySet()){ //只遍歷key System.out.println("key:"+key); } } // main 方法 public static void main(String[] args) { CollectionAndMapStudy s = new CollectionAndMapStudy(); s.mapIteratorTest(); } }