1. 程式人生 > >java之集合類詳解

java之集合類詳解

面試常見問題
ArrayList和LinkedList的聯絡和區別

                 1. ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。
                 2. 對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。 
                 3. 對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料
        Vector和ArrayList的聯絡和區別 

                 1、Vector是多執行緒安全的,而ArrayList不是,這個可以從原始碼中看出,Vector類中的方法很多有synchronized進行修飾,這樣就導致了                                Vector在效率上無法與ArrayList相比;

                 2、兩個都是採用的線性連續空間儲存元素,但是當空間不足的時候,兩個類的增加方式是不同的,很多網友說Vector增加原來空間的一倍,ArrayList增加原來空間的50%,其實也差不多是這個意思,不過還有一點點問題可以從原始碼中看出,一會兒從原始碼中分析。

                  3、Vector可以設定增長因子,而ArrayList不可以。


在說集合前我們不得不說一下陣列
陣列的作用:存放一組相同的資料型別(基本或物件)的資料,從而實現對資料的管理
優勢:可以快速的通過下標對陣列元素進行訪問,效率高
劣勢:容量實現定義好了,不能隨著需求變化而擴容
因此出現了更好的集合框架
一、陣列和集合的比較
陣列不是面向物件的,存在明顯的缺陷,集合彌補了陣列的缺點,比陣列更靈活更實用,而且不同的集合框架類可適用不同場合。如下:
·1:陣列能存放基本資料型別和物件,而集合類存放的都是物件的引用,而非物件本身!
·2:陣列容易固定無法動態改變,集合類容量動態改變。 
·3:陣列無法判斷其中實際存有多少元素,length只告訴了陣列的容量,而集合的size()可以確切知道元素的個數 
·4:集合有多種實現方式和不同適用場合,不像陣列僅採用順序表方式 
·5:集合以類的形式存在,具有封裝、繼承、多型等類的特性,通過簡單的方法和屬性即可實現各種複雜操作,大大提高了軟體的開發效率
二、java集合主要由兩個介面派生:Collection和Map,是集合框架的根介面。
collection的子介面:Set:介面 ---實現類: HashSet、LinkedHashSet
   set的子介面SortedSet介面---實現類:TreeSet
  List:介面---實現類: LinkedList,Vector,ArrayList 


List:有序列表,允許存放重複的元素; 
實現類: 
ArrayList:陣列實現,查詢快,增刪慢,輕量級;(執行緒不安全)
LinkedList:雙向連結串列實現,增刪快,查詢慢 (執行緒不安全)
Vector:陣列實現,重量級  (執行緒安全、使用少)


Set:無序集合,不允許存放重複的元素;允許使用null元素
HashSet 的後臺有一個HashMap;初始化後臺容量;只不過生成一個HashSet的話,系統只提供key的訪問; 如果有兩個Key重複,那麼會覆蓋之前的; 
實現類 
HashSet:equals返回true,hashCode返回相同的整數;雜湊表;儲存的資料是無序的。
LinkedHashSet:此實現與 HashSet 的不同之外在於,後者維護著一個運行於所有條目的雙重連結列表。儲存的資料是有序的。
雜湊表詳解http://www.bianceng.cn/Programming/sjjg/200705/1126.htm 
http://blog.csdn.net/feixiaoxing/article/details/6885657
http://blog.csdn.net/jdh99/article/details/8490704


子介面SortedSet,對Set排序實現類 :TreeSet:使用元素的自然順序對元素進行排序,或者根據建立 set 時提供的 Comparator 進行排序;二叉樹實現的; 
二叉樹詳解:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888/
http://blog.csdn.net/pony_maggie/article/details/38390513


Map的實現類:HashMap、TreeMap、LinkedHashMap、Hashtable等
HashMap:鍵值對,key不能重複,但是value可以重複;key的實現就是HashSet;value對應著放;允許null的鍵或值;
Hashtable:執行緒安全的,不允許null的鍵或值;
Properties::key和value都是String型別,用來讀配置檔案;
TreeMap:對key排好序的Map; key 就是TreeSet, value對應每個key; key要實現Comparable介面或TreeMap有自己的構造器; 
LinkedHashMap: 此實現與 HashMap 的不同之處在於,後者維護著一個運行於所有條目的雙重連結列表。儲存的數
據是有序的。

介面

簡述

實現

操作特性

成員要求

Set

成員不能重複

HashSet

外部無序地遍歷成員

成員可為任意Object子類的物件,但如果覆蓋了equals方法,同時注意修改hashCode方法。

TreeSet

外部有序地遍歷成員;附加實現了SortedSet, 支援子集等要求順序的操作

成員要求實現caparable介面,或者使用 Comparator構造TreeSet。成員一般為同一型別。

LinkedHashSet

外部按成員的插入順序遍歷成員

成員與HashSet成員類似

List

提供基於索引的對成員的隨機訪問

ArrayList

提供快速的基於索引的成員訪問,對尾部成員的增加和刪除支援較好

成員可為任意Object子類的物件

LinkedList

對列表中任何位置的成員的增加和刪除支援較好,但對基於索引的成員訪問支援效能較差

成員可為任意Object子類的物件

Map

儲存鍵值對成員,基於鍵找值操作,compareTo或compare方法對鍵排序

HashMap

能滿足使用者對Map的通用需求

鍵成員可為任意Object子類的物件,但如果覆蓋了equals方法,同時注意修改hashCode方法。

TreeMap

支援對鍵有序地遍歷,使用時建議先用HashMap增加和刪除成員,最後從HashMap生成TreeMap;附加實現了SortedMap介面,支援子Map等要求順序的操作

鍵成員要求實現caparable介面,或者使用Comparator構造TreeMap。鍵成員一般為同一型別。

LinkedHashMap

保留鍵的插入順序,用equals 方法檢查鍵和值的相等性

成員可為任意Object子類的物件,但如果覆蓋了equals方法,同時注意修改hashCode方法。

IdentityHashMap

使用== 來檢查鍵和值的相等性。

成員使用的是嚴格相等

WeakHashMap

其行為依賴於垃圾回收執行緒,沒有絕對理由則少用


三、Collection常見方法
add(E e); addAll(Collection c);clear();contains(Obj o);返回是否包含指定的元素(true false) 


containsAll(Collection c)是否包含c中所有元素 isEmpty(); iterator();remove();size();toArray();返回


collection中所有元素的陣列
四、集合的遍歷
     1、增強for迴圈 for(Obj o:c){syso(o)}
     2、使用iterator , Iterator it=c.iterator;
          while(it.hasNext()){Object o = it.next()}
     3、普通迴圈:for(Iterator it=c.iterator();it.hasNext();){it.next() }

五、程式碼例項

 1、 ArrayList
import java.util.ArrayList;  
  
/** 
 *  
 * 關於ArrayList的基本操作  
 * 其它操作感興趣的讀者可以自己結合原始碼實現一下 
 *  * @author erqing 
 *  
 */  
public class ListTest {  
  
    public static void main(String[] args) {  
  
        /* 新建一個ArrayList */  
        ArrayList<String> list = new ArrayList<String>();  
        System.out.println("初始化大小:" + list.size());  
  
        /* 新增元素 */  
        list.add("zzz");  
        list.add("egg");  
        list.add("hell");  
        list.add("child");  
        System.out.println("當前容量:" + list.size());  
  
        /* 將ArrayList的大小和實際所含元素的大小設定一致 */  
        list.trimToSize();  
  
        /* 遍歷 */  
        for (String string : list) {  
            System.out.println(string);  
        }  
  
        /* 在指定位置插入元素 */  
        list.add(2, "zhu");  
  
        for (String string : list) {  
            System.out.println(string);  
        }  
  
        System.out.println("--------------");  
  
        /* 清空list */  
        list.clear();  
  
        /* 遍歷 */  
        for (String string : list) {  
            System.out.println(string);  
        }  
        System.out.println("--------------");  
    }  
}  
  2、LinkedList
import java.util.LinkedList;  
  
public class LinkedListTest {  
      
    public static void main(String[] args) {  
  
        /* 新建一個list */  
        LinkedList<Integer> list = new LinkedList<Integer>();  
        System.out.println(list.size());  
  
        /* 向list中新增元素 */  
        list.add(222);  
        list.add(111);  
        list.add(0);  
        list.add(3333);  
        list.add(8888);  
          
        System.out.println(list.size());  
  
        /* 遍歷list */  
        for (Integer integer : list) {  
            System.out.println(integer);  
        }  
  
        /* 獲取第一個元素 ,即header的next域*/  
        System.out.println("第一個元素是:" + list.getFirst());  
          
        /*獲取最後一個元素,即header的previous域*/  
        System.out.println("最後一個元素是:"+list.getLast());  
    }  
}  

3、hashset
	public static void main(String[] args) {
		Set set = new HashSet();
		set.add("a");
		set.add("b");
		System.out.println(set);
		Student stu= new Student(18, "小名", 60);
		set.add(stu);//呼叫第一個物件的hashcode方法  調  equals
		set.add(new Student(19, "小明", 60));
		set.add(new Student(19, "小明", 60));
		set.add(new Student(20, "小明", 61));
		System.out.println(set);
	}
4、treeset
import java.util.ArrayList;
import java.util.HashSet;
import java.util.TreeSet;

/**
 * 使用treeset存放一組學生成績
 * 	1、可以自動排序(系統類  自然排序)
 *  2、不可重複(去重)
 *  3、只能存放一種資料型別
 *  ---存放到 treeset中的元素必須要具有比較能力
 *  	呼叫compareTo() 如果得到的結果為0 , 兩個元素相等
 *      1 ---》排到後面
 *      -1 --->排到前面
 *      
 *  hashset:-->hashtable(雜湊表)
 *  treeset:-->二叉樹,紅黑樹演算法
 *  每存入一個元素就會呼叫一次compareTo方法
 * @author Administrator
 *
 */
import java.util.Comparator;
/**
 * 外部比較器,當系統類提供的比較規則滿足不了需求時使用
 *   1、自己建立一個比較器  實現  Comprator介面 ,新增一個泛型(需要比較的資料型別)
 *   2、重寫comprae方法,用來比較,引數是兩個需要比較的物件
 * @author Administrator
 *
 */
public class MyStrCompartor implements Comparator<String>{

	@Override
	public int compare(String o1, String o2) {
		//按照字串長度排序
		
		return o1.length() - o2.length();
	}

}


public class TestTreeSet02 {

	public static void main(String[] args) {
		//使用外部比較器,
		//1 拿到比較器的物件
		MyStrCompartor mcom = new MyStrCompartor();
		//2在建立集合時,呼叫有參的構造方法,把比較器傳進去
		//3、在treeset中新增元素時,會優先呼叫自定義比較器的方法
		//treeset專用
		TreeSet ts = new TreeSet(mcom);
//		ts.add(20);//自動裝箱
//		ts.add(1);
//		ts.add(100);
//		ts.add(7);
//		ts.add(8);
//		ts.add(100);
		System.out.println(ts);
		//需求:不希望按照系統的排序來排列
		//自己建立一個比較規則
		ts.add("xiaomi32313");
		ts.add("zhangliguo5");
		ts.add("asima1");
		ts.add("baibaibai4");
		ts.add("sansan2");
//		ts.add(new Student("yushen", 19, 19));
//		ts.add(new Student("xiaoming", 19, 19));
//		ts.add(new Student("axiaoming1", 19, 18));
		System.out.println(ts);
	}

}

5、hashmap
import java.util.HashMap;  
import java.util.Map;  
import java.util.Set;  
  
/** 
 * HashMap的使用 
 * @author erqing 
 *  
 */  
public class MapTest {  
  
    public static void main(String[] args) {  
  
        /* 初始化map */  
        Map<String, Integer> map = new HashMap<String, Integer>();  
        System.out.println("HashMap的初始值:" + map.size());  
        System.out.println("HashMap是否為空:" + (map.isEmpty() ? "是" : "否"));  
  
        /* 想map中新增元素 */  
        map.put("erqing", 1);  
        map.put("niuniu", 2);  
        map.put("egg", 3);  
        System.out.println(map.size());  
        ;  
        System.out.println("HashMap是否為空:" + (map.isEmpty() ? "是" : "否"));  
  
        /* 遍歷HashMap中的元素 */  
        Set<String> set = map.keySet();  
        for (String s : set) {  
            System.out.println(s + " " + map.get(s) + " " + "hashcode:"  
                    + s.hashCode());  
        }  
  
        /*檢測是否含有某個Key*/  
        System.out.println(map.containsKey("egg"));  
          
        /*檢測是否含有某個Value*/  
        System.out.println(map.containsValue(2));  
          
        /*列印hashCode*/  
        System.out.println(map.hashCode());  
    }  
}  
/*
輸出:
HashMap的初始值:0
HashMap是否為空:是
3
HashMap是否為空:否
niuniu 2 hashcode:-1045196352
egg 3 hashcode:100357
erqing 1 hashcode:-1294670850
true
true
1955200455
*/

6、treemap
public static void main(String[] args) {  
          
        SortedMap<String, Integer> map = new TreeMap<String, Integer>();  
        map.put("zgg", 1);  
        map.put("erqing", 3);  
        map.put("niu", 0);  
        map.put("abc", 2);  
        map.put("aaa", 5);  
//	map.put(1004, new Student("04",18 ,1004));
//	map.put(1005, new Student("05",18 ,1005));    也能存new
        Set<String> keySet = map.keySet();  
        for (String string : keySet) {  
            System.out.print(map.get(string)+" ");  
        }  
    }  
//輸出:5 2 3 0 1



更多內容:http://blog.csdn.net/zhangerqing/article/details/8122075


持續更新,歡迎大家一起交流
郵箱:[email protected]
未完,待續