<正則吃餃子>:關於集合的簡單整理總結

項目中用到的集合不可謂很少,對於本身的一次面試,要求說下本身用過的集合,本身開始說的並不系統也不完整,一直耿耿於懷,特整理一下,以備後期之用和幫助後來者。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();

	}

}
相關文章
相關標籤/搜索