黑馬程序員—集合

---------------------- JavaEE+Android、Java培訓、期待與您交流! ----------------------


所謂集合,就是爲方便對多個對象的操作,對對象進行存儲。集合就是存儲對象最常用的一種方式。

集合與數組的區別:
數組:可存儲同種類型的數據,但長度固定,也可存儲基本類型的數據
集合:只可存儲對象,長度可變,類型可以不同。

集合的特點:
只用於存儲對象,長度可變,也可存不同類型的對象。集合是一個接口,將每種容器的共性提取,形成的一個體系。

集合體系如圖:

集合中的共性方法:

1、增加:
   add(Object obj);    添加元素

2、刪除:
   remove();        刪除集合中指定參數的元素
   removeAll();     刪除當前集合中與另一集合相同的元素,即只保留與另一集合不同的元素
   clear();         清空集合中的元素,集合還存在

3、獲取集合長度:
   size();          獲取集合長度,即集合元素的個數

4、修改:
   set(int index,e);   將指定位置(index)上的元素修改爲給定的參數e

5、判斷:
   boolean contains(e);   判斷給定元素e是否存在於集合中

6、迭代器:iterator()     集合取出元素的方式
   boolean hasNext();     判斷是否還有下一個元素
   next();                取出下一個元素

List集合

List集合包含三個子類:ArrayList、LinkedList以及Vector等。具體區別如下:
1、ArrayList:底層的數據結構時數組結構
      特點:查詢速度很快,因爲有索引(角標),但增刪速度稍慢。是線程不同步的。
2、LinkedList:底層使用的是鏈表數據結構
      特點:增刪速度很快,但查詢速度稍慢,因爲每一個元素都鏈接到前一元素。
3、Vector:底層是數組結構,JDK1.0出現,比較老。
      特點:增刪查詢都很慢,被ArrayList替代了,線程是同步的。

List集合特有的方法:
1、增加:
   add(int index,e);               ----->  在指定位置增加給定的元素
   addAll(int index,Collection);   ----->  在指定位置增加給定集合中的所有元素,若省略位置參數,則在當前集合的後面依次添加元素

2、刪除:
   remove(int index); ----->  刪除集合中指定位置上的元素
   
3、修改:
   set(int index,e);  ----->  將指定位置(index)上的元素修改爲給定的參數e

4、查詢:
   get(int index);    ----->  獲取指定位置上的元素
   indexOf(e);        ----->  通過指定元素獲取其在集合中的位置
   subList(int from,int to);    ----->  獲取從from到to位置上的元素
   Iterator listIterator();     ----->  返回Iterator接口類型值
注:
1、listIterator是List特有的迭代器,是Iterator子接口。在迭代時,不可通過集合對象的方法操作集合中的元素,因爲會發生ConcurrentModficationException異常。所以,在迭代時,只能用迭代器的方法操作,可Iterator方法是有限的,若想要其他操作如增刪改寫等,就需要使用子接口,即ListIterator,該接口只能通過List集合的listIerator方法獲取。
2、在迭代時,循環中的next()調用一次,就要對hasNext判斷一次,不可判斷一次調用兩次。
3、List集合判斷元素是否相同,一句的是元素的equals方法,其中,contains中就是調用的equals方法。

LinkedList類特有方法:
1、增加:
   offerFirst(obj);   ----->  在集合頭部添加給定的元素
   offerLast(obj);    ----->  在集合尾部添加給定的元素

2、獲取:
   peekFirst();   ----->  獲取集合第一個元素,若集合中沒有元素,則返回null
   peekLast();    ----->  獲取集合最後一個元素,若集合中沒有元素,則返回null
   
3、刪除:
   pollFirst();  ----->  獲取並刪除集合第一個元素 ,若集合中沒有元素,則返回null
   pollLast();   ----->  獲取並刪除集合最後一個元素,若集合中沒有元素,則返回null

Set集合

Set集合的特點:
1)集合中的元素師無需的(存入和取出的順序不一定一致),且元素不可重複。
2)Set集合的功能和Collection集合的是一樣的,並沒有什麼特別的方法。

HashSet類特點:
   底層數據結構時哈希表,且元素取出方式只有迭代器方法
HashSet通過元素的hasCode和equals方法來保證元素的唯一性

TreeSet類特點:
底層的數據結構爲二叉樹結構
可對Set集合中的元素進行排序,是因爲:TreeSet類實現了Comparable接口,該接口強制讓增加到集合中的對象進行了比較,需要複寫compareTo方法,才能讓對象按指定需求(如人的年齡大小比較等)進行排序,並加入集合。
注意:java中的很多類都具備比較性,其實就是實現了Comparable接口。

Map集合

Map集合中的子類:
1、HashTable:特點: 底層是哈希表數據結構,不可存入null鍵和null值。該集合是線程同步的,效率較低
2、HashMap:特點:底層是哈希表數據結構,允許使用null值和null鍵。該集合是線程同步的,效率較高
3、TreeMap:特點: 底層是二叉樹數據結構,線程不同步,可以用於給Map集合中的鍵值進行排序,和Set很像,其實,Set集合的底層就是使用了Map集合。

兩種獲取集合元素的方法:

1、keySet()方法獲取元素
原理:將Map集合中的所有鍵存入到Set集合中,因爲Set集合具備迭代器,所以可以用迭代方式取出所有的鍵,再根據get方法獲取每一個鍵對應的值。簡單說就是:Map集合---->Set集合 ---->迭代器取出
示例:
<span style="font-family: Arial; font-size: 10px; ">//keySet集合測試

import java.util.*;
class KeySetDemo 
{
	public static void main(String[] args) 
	{
		//創建Map集合,並添加元素
		Map<Integer,String> map = new HashMap<Integer,String>();
		map.put(2,"zhangsan");
		map.put(6,"lisi");
		map.put(3,"wangwu");
		map.put(4,"heihei");
		map.put(5,"xixi");
		//獲取map集合中的所有鍵的Set集合
		Set<Integer> keySet = map.keySet();
		//有了Set集合就可以獲取其迭代器,取值
		Iterator<Integer> it = keySet.iterator();
		while (it.hasNext())
		{
			Integer i = it.next();
			String s = map.get(i);
			System.out.println(i + " = " + s);
		}
	}
}
</span>

2、entrySet()方法獲取元素:
原理:將Map集合中的映射關係存入到了Set集合中,而這個映射關係的數據類型是Map.Entry,在通過迭代器將映射關係存入到Map.Entry集合中,並通過其中的getKey()和getValue()放取出鍵值。
示例:
<span style="font-family: Arial; font-size: 10px; ">/*
entrySet取出方式:
*/
import java.util.*;
class EntrySetDemo
{
	public static void main(String[] args) 
	{
		//創建集合,存入元素
		Map<String,String> map = new HashMap<String,String>();
		map.put("01","lisi1");
		map.put("02","lisi2");
		map.put("03","lisi3");
		map.put("04","lisi4");
		//獲取map集合中的所有鍵,存入到Set集合中,
		Set<Map.Entry<String,String>> entry = map.entrySet();
		//通過迭代器取出map中的鍵值關係,迭代器接收的泛型參數應和Set接收的一致
		Iterator<Map.Entry<String,String>> it = entry.iterator();
		while (it.hasNext())
		{
			//將鍵值關係取出存入Map.Entry這個映射關係集合接口中
			Map.Entry<String,String>  me = it.next();
			//使用Map.Entry中的方法獲取鍵和值
			String key = me.getKey();
			String value = me.getValue();
			System.out.println(key + " : " + value);
		}
	}
}
</span>

練習

獲取該字符串中的字母出現的次數,如:"sjokafjoilnvoaxllvkasjdfns";希望打印的結果是:a(3)c(0).....

分析:

通過結果發現,每一個字母都有對應的次數。說明字母和次數之間都有映射關係。注意了,當發現有映射關係時,可以選擇map集合。因爲map集合中存放就是映射關係。

思路:

1,將字符串轉換成字符數組。因爲要對每一個字母進行操作。

2,定義一個map集合,因爲打印結果的字母有順序,所以使用treemap集合。

3,遍歷字符數組。

將每一個字母作爲鍵去查map集合。

如果返回null,將該字母和1存入到map集合中。

如果返回不是null,說明該字母在map集合已經存在並有對應次數。

那麼就獲取該次數並進行自增。,然後將該字母和自增後的次數存入到map集合中。覆蓋調用原理鍵所對應的值。

4,將map集合中的數據變成指定的字符串形式返回。

代碼如下:
<span style="font-family:Arial;font-size:10px;">import java.util.*;
class MapTest
{
	public static void main(String[] args) 
	{
		String s = "abcsjokafjoilnvoaxllvkasjdfnsde 0[fga8/-abbdc";
		String str = LetterNum(s);
		System.out.println(str);
	}

	public static String LetterNum(String str)
	{
		//將字符串轉換成字符數組,因爲對每個字母進行操作
		char[] ch = str.toCharArray();
		//定義一個Map集合,因爲打印結果的字母有順序,所以使用TreeMap集合
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		int count = 0;
		//遍歷字符數組,將每一個字母作爲鍵去查map集合,
		for (int i=0;i<ch.length;i++)
		{
			//判斷集合是否含有其他非字母,是則再次循環
			if (!(ch[i]>= 'a' && ch[i] <= 'z' || ch[i] >= 'A' && ch[i] <= 'Z'))
				continue;
			//取出鍵對應的值,不爲則計數器加1,存入集合,並將計數器清零,用於下一個字母
			Integer value = tm.get(ch[i]);
			if (value != null)
				count = value;
			count++;
			tm.put(ch[i],count);
			count = 0;
		}
		//創建字符串容器,存入取出的鍵值即按順序排列的字符串
		StringBuilder sb = new StringBuilder();
		//迭代器取出相應鍵值,並存入字符串容器
		Iterator<Map.Entry<Character,Integer>> it = tm.entrySet().iterator();
		while (it.hasNext())
		{
			Map.Entry<Character,Integer> me = it.next();
			Character key = me.getKey();
			Integer value = me.getValue();
			sb.append(key + "(" + value + ")");
		}
		return sb.toString();
	}
}</span>

工具類

Collections工具類

在Collections工具類中很多方法是用於對List集合進行操作的,如比較,查找,隨機排序等等
1、集合的各種方法:

1)查找:

      T max(Collection<? extends T> coll)    --->    根據集合的自然順序,獲取coll集合中的最大元素

      T max(Collection<? extends T> coll,Comparator<? super T> comp)    --->   根據指定比較器comp的順序,獲取coll集合中的最大元素

      int binarySearch(Lsit<? extends Comparable<? super T>> list,Tkey)    --->   二分法搜索list集合中的指定對象

2)替換:

      void fill(List<? super T> list, T obj)        --->   將list集合中的全部元素替換成指定對象obj

      boolean replaceAll(List<T> lsit,T oldVal,T newVal)     --->   使用newVal替換list集合中的oldVal值

3)排序:

      void shuffle(List<?> list)     --->   使用默認隨機源對list集合中的元素進行隨機排序

      void sort(Lsit<T> list)          --->   根據自然順序對list集合中的元素進行排序

      void sort(List<T> lsit,Comparator<? super T> c)     --->   根據指定比較器c的排序方式對list集合進行排序

4)反轉

      reverse(List<?> list)     --->   反轉list集合中元素的順序

      Comparator reverseOrder()     --->   返回一個比較器,強行逆轉了實現Comparable接口的對象的自然順序

      Comparator reverseOrder(Comparator<T> cmp)     --->   返回一個比較器,強行逆轉了指定比較器的順序


Arrays工具類

1、Lsit<T> asList(T... a)    --->    將數組轉換爲集合

注意:將數組轉換成集合,不可使用集合的增刪方法,因爲數組的長度是固定的,如果進行增刪操作,則會產生UnsupportedOperationException的編譯異常。

a.如果數組中的元素都是對象,則變成集合時,數組中的元素就直接轉爲集合中的元素

b.如果數組中的元素都是基本數據類型,那麼會將該數組作爲集合中的元素存在

2、binarySearch():查找方法,fill():替換方法,sort():排序方法等

特點:可對數組元素進行相應操作,可以接受除boolean之外的其他各種基本數據類型及有序的引用類型數組的參數,且還可以對指定元素的範圍,並可根據指定比較器進行相應的操作

如:sort(T[] a,Comparator<? super T> c) 

        fill(int[]a,int from,int to)等

3、String toString() 可以接收各種數組類型參數,並返回指定數組內容的字符串表現形式

4、集合轉爲數組

      void toString(String[] s)  --->  將集合轉爲指定數組s,並可通過Arrays.toString(s)獲取數組s中的元素

1)指定類型的數組定義的長度:

a.當指定類型的數組長度小於了集合的size,那麼該方法內部會創建一個新的數組,長度爲集合的size

b.當指定類型的數組長度大於了集合的size,就不會創建數組,而是使用傳遞進來的數組,並且多出的元素的值爲null

2)爲何將集合轉爲數組:爲了限定對集合中元素的操作,如增刪,因爲想對創建的集合不做增刪方面的操作。


小知識點


一、增強for循環

1、格式:

      for(數據類型 變量名 : 被遍歷的集合(Collection)或數組){執行語句}

2、說明:

1)對集合進行遍歷,只能獲取集合的元素,但是不能對集合進行操作。

2)迭代器除了遍歷外,還可進行remove集合中元素的操作,如果使用ListIterator,還可在遍歷過程中,對集合進行增刪改查的操作。

3、傳統for循環和增強for循環區別:

      增強for循環有侷限性。必須有被遍歷的目標;而傳統for循環有索引。所以建議在遍歷數組時,使用傳統for循環。

示例:

<span style="font-family: Arial; font-size: 10px; ">import java.util.*;
class ForEachDemo
{
	//打印方法
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}

	//測試
	public static void main(String[] args) 
	{
		//創建集合
		ArrayList<String> as = new ArrayList<String>();
		as.add("01-a");
		as.add("02-b");
		as.add("03-c");
		System.out.println("原集合" + as);
		//增強for循環取出元素
		for (String s : as)
		{
			System.out.println(s);
		}
		System.out.println("-------------------------");
		//創建HashMap集合
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(1,"a");
		hm.put(2,"b");
		hm.put(3,"c");
		hm.put(4,"d");
		System.out.println("hm原集合:" + hm);
		//增強for循環的兩種方式測試
		//keySet方法
		sop("keySet方法:|--");
		for(Integer i : hm.keySet())
		{
			sop(i + ":-" + hm.get(i));			
		}
		//entrySet方法
		sop("entrySet方法--");
		for(Map.Entry<Integer,String> me : hm.entrySet())
		{
			sop(me.getKey() + "-->" + me.getValue());
		}
	}
}</span>

二、可變參數:

如果在參數列表中傳入多個參數,個數不確定,每次都要複寫該方法,可變參數的出現就可以省去複寫的麻煩,而直接對數組進行操作

注意:可變參數一定要定義在參數列表的後面。

示例:

<span style="font-family: Arial; ">	......
	//1.5版本前寫法
	public static void show(int a,int b)
	{
		System.out.println(a + " :" + b);
	}
	//1.5新特性,可加入更多的值
	public static void show(int... arr)
	{
		System.out.println(arr.length);//結果爲數組arr的長度
		System.out.println(arr);//arr的地址值
	}
	public static void print(String... s)
	{
		//遍歷字符串數組s
		for(String str : s)
		{
			System.out.print(str);
		}
		System.out.println();
	}
	
	......</span>

三、靜態導入:

        靜態導入,是將類中的所有靜態成員導入進來,但需要注意的是,當導入的兩個類中有同名成員時,需要在成員前加上相應的類名。

        當類名重名時,需要制定具體的包名;當方法名重名時,制定具體所屬的對象或類。

1、import static java.util.Arrays.*;       ---> 寫入的是Arrays類中的所有靜態成員。

2、import static java.lang.System.*;  ---> 導入了System類中的所有靜態成員

<span style="font-family: Arial; font-size: 10px; ">import java.util.*;
import static java.util.Arrays.*;//導入的是Arrays類中的所有靜態成員
import static java.lang.System.*;//導入的是System類中的所有靜態成員
class Demo
{
	public static void main(String [] args)
	{
		int[] arr = {2,7,6,3};
		sort(arr);
		out.println(Arrays.toString(arr));//此處不可省略Arrays,原因見下

	}
}</span>



---------------------- JavaEE+Android、Java培訓、期待與您交流! ----------------------

詳細請查看: http://edu.csdn.net

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章