API-集合框架-Map、Collections、Arrays

一、Map集合
 
1、Map集合概述
Map集合:該集合存儲鍵值對。一對一對往裏存。而且要保證鍵的唯一性。
 
Map子類對象
    |--Hashtable:底層是哈希表數據結構,不可以存入null鍵null值。該集合是線程同步的。JDK1.0,效率低。
    |--HashMap:底層是哈希表數據結構。允許使用null鍵null值,該集合是不同步的。JDK1.2,效率高。
    |--TreeMap:底層是二叉樹數據結構。線程不同步。可以用於給Map集合中的鍵進行排序。
Map和Set很像。其實Set底層就是使用了Map集合。
 
2、Map共性方法
a、添加
        put(K key,V value);//添加元素,如果出現添加時,相同的鍵,那麼後添加的值會覆蓋原有鍵對應值,並put方法會返回被覆蓋的值。
        voidputAll(Map <? extends K,? extends V> m);//添加一個集合
b、刪除
        clear();//清空
        remove(Object key);//刪除指定鍵值對
c、判斷
        containsKey(Objectkey);//判斷鍵是否存在
        containsValue(Objectvalue)//判斷值是否存在
        isEmpty();//判斷是否爲空
d、獲取
        get(Object key);//通過鍵獲取對應的值
        size();//獲取集合的長度
        values();//獲取Map集合中所有的值,返回一個Collection集合
還有兩個取出方法,接下來會逐個講解:
        Set<Map.Entry<K,V>>entrySet();
        Set<K>  keySet();
代碼示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class MapDemo 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		
		//put方法添加元素時,如果添加相同的鍵,那麼後添加的值會覆蓋原有鍵對應的值,並且會返回被覆蓋的值。
		System.out.println("put:"+map.put("01","wangwu"));
        System.out.println("put:"+map.put("01","zhangsan1"));
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
 
		System.out.println("containsKey:"+map.containsKey("02"));
		System.out.println("remove:"+map.remove("07"));
 
		map.put("08",null);
		System.out.println("get:"+map.get("02"));
		//可以通過get方法的返回值來判斷一個鍵是否存在。通過返回null來判斷。
 
		//獲取map集合中所有的值
		Collection<String> coll = map.values();
		System.out.println(coll);
		System.out.println(map);
	}
}</span>
 
3、Map集合的兩種取出方式 
Map集合的取出原理:將Map集合轉成Set集合。再通過迭代器取出。
1、Set<k> keySet():將Map中所有的鍵存入到Set集合。因爲Set具備迭代器。所以可以通過迭代方式取出所有的鍵,再通過get方法。獲取每一個鍵對應的值。
2、Set<Map.Entry<k,v>> entrySet():將Map集合中的映射關係存入到Set集合中,而這個關係的數據類型就是:Map.Entry
代碼示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class MapDemo1
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		
        map.put("01","zhangsan1");
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		map.put("04","zhangsan4");
 
		//先取出Map集合的所有鍵的Set集合,keySet();
		Set<String> keyset = map.keySet();
 
		//有了Set集合,就可以獲取其迭代器。
		Iterator<String> it = keyset.iterator();
 
		while(it.hasNext())
		{
			String key = it.next();
			//有了鍵就可以通過Map集合的get方法獲取其對應的值。
			String value = map.get(key);
			System.out.println("keySet:key="+key+",value="+value);
		}
		
		//將Map集合中的映射關係取出,存入到Set集合中。
		Set<Map.Entry<String,String>> entryset = map.entrySet();
 
		Iterator<Map.Entry<String,String>> it1 = entryset.iterator();
 
		while(it1.hasNext())
		{
			Map.Entry<String,String> me = it1.next();
			//有了鍵就可以通過Map集合的get方法獲取其對應的值。
			String key = me.getKey();
			String value = me.getValue();
			System.out.println("entrySet:key="+key+",value="+value);
		}
 	}
}</span>
例:將學生按姓名、年齡排序
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
/* 
每一個學生都有對應的歸屬地。 
學生Student,地址String。 
學生屬性:姓名,年齡。 
注意:姓名和年齡相同的視爲同一個學生。 
保證學生的唯一性。 
思路:1、描述學生類 
      2、定義一個Map集合,存儲學生對象和地址值 
      3、獲取Map中的元素 
*/
 
 
class Student implements Comparable<Student>
	{
		private String name;
		private int age;
		Student(String name,int age)
		{
			this.name = name;
			this.age = age;
		}
	    public int compareTo(Student s)
		{
			int num = this.name.compareTo(s.name);
			if(num==0)
				return new Integer(this.age).compareTo(new Integer(s.age));
			return num;
 
		}
		public int hashCode()//重寫hashcode
		{
			return name.hashCode()+age*39;
		}
		public boolean equals(Object obj)//重寫equals
		{
			if(!(obj instanceof Student))
				throw new ClassCastException("類型不匹配");
			Student s = (Student)obj;
			return this.name.equals(s.name) && this.age == s.age;
		}
 
		public String getName()
		{
			return name;
		}
		public int getAge()
		{
			return age;
		}
		public String toString()
		{
			return name+":"+age;
		}
	}
 
class StuAgeComparator implements Comparator<Student>
{
	public int compare(Student s1,Student s2)
	{
		int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
			if(num==0)
				return s1.getName().compareTo(s2.getName());
			return num;
	}
}
class MapTest 
{
	public static void main(String[] args) 
	{
		//HashMap
		HashMap<Student,String> hm = new HashMap<Student,String>();
 
		hm.put(new Student("lasi1",21),"beijing");
		hm.put(new Student("lasi2",22),"shanghai");
		hm.put(new Student("lasi3",23),"nanjing");
		hm.put(new Student("lasi4",24),"wuhan");
		hm.put(new Student("lasi4",24),"tianjin");
		
		//第一種取出方式 keySet
		Set<Student> keyset = hm.keySet();
		Iterator<Student> it = keyset.iterator();
		while(it.hasNext())
		{
			Student stu = it.next();
			String add = hm.get(stu);
			System.out.println("HashMap第一種取出方式keySet:"+stu.toString()+"--"+add);
		}
			
		System.out.println("------------------------------------");
 
		//第二種取出方式 entrySet
		Set<Map.Entry<Student,String>> entryset = hm.entrySet();
		Iterator<Map.Entry<Student,String>> it1 = entryset.iterator();
		while(it1.hasNext())
		{
			Map.Entry<Student,String> me = it1.next();
			Student stu = me.getKey();
			String add = me.getValue();
			System.out.println("HashMap第二種取出方式 entrySet:"+stu.toString()+"::"+add);
		}
		System.out.println("------------------------------------");
 
		//TreeMap
		TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuAgeComparator());
 
		tm.put(new Student("blisi1",21),"beijing");
		tm.put(new Student("alisi2",22),"shanghai");
		tm.put(new Student("dlisi3",23),"nanjing");
		tm.put(new Student("clisi4",24),"wuhan");
		tm.put(new Student("clisi4",24),"tianjin");
 
		//第二種取出方式 entrySet
		Set<Map.Entry<Student,String>> entryset1 = tm.entrySet();
		Iterator<Map.Entry<Student,String>> it2 = entryset1.iterator();
		while(it2.hasNext())
		{
			Map.Entry<Student,String> me = it2.next();
			Student stu = me.getKey();
			String add = me.getValue();
			System.out.println("TreeMap比較器 按年齡排序:"+stu.toString()+"..."+add);
		}
 
		System.out.println("------------------------------------");
 
		TreeMap<Student,String> tm1 = new TreeMap<Student,String>();
 
		tm1.put(new Student("blisi1",21),"beijing");
		tm1.put(new Student("alisi2",22),"shanghai");
		tm1.put(new Student("dlisi3",23),"nanjing");
		tm1.put(new Student("clisi4",24),"wuhan");
		tm1.put(new Student("clisi4",24),"tianjin");
 
		//第二種取出方式 entrySet
		Set<Map.Entry<Student,String>> entryset2 = tm1.entrySet();
		Iterator<Map.Entry<Student,String>> it3 = entryset2.iterator();
		while(it3.hasNext())
		{
			Map.Entry<Student,String> me = it3.next();
			Student stu = me.getKey();
			String add = me.getValue();
			System.out.println("TreeMap元素自身比較性 按姓名排序:"+stu.toString()+"..."+add);
		}
 	}
}</span>
運行結果:
uploading.4e448015.gif轉存失敗重新上傳取消
例:"fajkgvzvbzjhfaf"獲取該字符串中的字母出現的次數,希望打印的結果是:a(1)c(2).....
<span style="font-family:Microsoft YaHei;font-size:14px;">/*
"fajkgvzvbzjhfaf"獲取該字符串中的字母出現的次數,
希望打印的結果是:a(1)c(2).....
通過結果發現,每個字母都有對應的次數,說明字母和次數之間有映射關係
何時使用Map集合:當量數據之間存在着映射關係的時候,就應該想到使用Map集合。
 
思路:1、將字符串轉換爲字符數組 ,因爲要對每一個字母進行操作。
      2、定義一個Map集合,因爲打印結果的字母有順序,所以使用TreeMap集合。
      3、遍歷字符數組。
			將每一個字母作爲鍵去查Map集合。
			如果返回null,將該字母和1存入到Map集合中。
			如果返回不是null,說明該字母在Map集合已經存在並有對應次數。
			那麼就獲取該次數並進行自增。然後將該字母和自增後的次數存入到Map集合中,覆蓋掉原來鍵所對應的值。
 
	
	  用數組去遍歷集合,如果集合中有該字母則次數加1,如果集合中沒有則存入 
      4、將Map集合中的數據變成指定的字符串形式返回。
*/
 
import java.util.*;
class  MapTest1
{
	public static void main(String[] args) 
	{
		charCount("fajkgvzvbzjhfaf");
	}
	
	public static String charCount(String s)
	{
		char[] ch = s.toCharArray();
 
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		
		for (int x=0; x<ch.length; x++)
		{
			Integer value = tm.get(ch[x]);
			if (value==null)
				tm.put(ch[x],1);
			else
			{
				value = value+1;
				tm.put(ch[x],value);
			}
		}
		
 
		Set<Character> keyset = tm.keySet();
 
		Iterator<Character> it = keyset.iterator();
		while(it.hasNext())
		{
			Character c = it.next();
			Integer i = tm.get(c);
			System.out.print(c.toString()+"("+i+")");
		}
		return null;
	}
}</span>
運行結果:
uploading.4e448015.gif轉存失敗重新上傳取消
4、Map擴展
Map擴展知識:Map集合被使用是因爲具備映射關係。
例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
/*
Map擴展知識:Map集合被使用是因爲具備映射關係。
"yureban"   "01"  "zhangsan"
"yureban"   "02"  "lisi"
"jiuyeban"  "01"  "wangwu"
"jiuyeban"  "02"  "zhaoliu"
*/
class Student
{
	private String num;
	private String name;
	Student(String num,String name)
	{
		this.num = num;
		this.name = name;
	}
	public String toString()
	{
		return num+"...."name;
	}
}
class  MapTest2
{
	public static void main(String[] args) 
	{
		HashMap<String,String> yure = new HashMap<String,String>();
 
		yure.put("01","zhangsan");
		yure.put("02","lisi");
		
		HashMap<String,String> jiuye = new HashMap<String,String>();
 
		jiuye.put("01","wangwu");
		jiuye.put("02","zhaoliu");
 
		HashMap<String,HashMap<String,String>> czbk =new  HashMap<String,HashMap<String,String>>();
 
		czbk.put("yureban",yure);
		czbk.put("jiuyeban",jiuye);
 
		Set<String> keyset = czbk.keySet();
 
		Iterator<String> it = keyset.iterator();
		while(it.hasNext())//雙重循環
		{
			String s = it.next();
			HashMap<String,String> room = czbk.get(s);
 
			Set<String> keyset1 = room.keySet();
 
			Iterator<String> it1 = keyset1.iterator();
			while(it1.hasNext())//雙重循環
			{
				String num = it1.next();
				String name = room.get(num);
				System.out.println(s+":"+num+"--"+name);
			}
		}	
	}
}</span>
運行結果:
uploading.4e448015.gif轉存失敗重新上傳取消
 
二、Collections
 
1、概述
        Collections是對集合框架的一個工具類。它裏邊的方法都是靜態的,不需要創建對象。並未封裝特有數據。
        在Collections工具類中大部分方法是用於對List集合進行操作的,如比較,二分查找,隨機排序等。
 
2、常見操作
a、排序:        
        void sort(Lsit<T> list);//根據自然順序對list集合中的元素進行排序
        void sort(List<T> lsit,Comparator<? super T> c);//根據指定比較器c的排序方式對list集合進行排序
b、查找
        Tmax(Collection<? extends T> coll);//根據集合的自然順序,獲取coll集合中的最大元素
        Tmax(Collection<? extends T> coll,Comparator<? super T> comp);//根據指定比較器comp的順序,獲取coll集合中的最大元素
        intbinarySearch(Lsit<? extends Comparable<? super T>> list,Tkey);//二分法查找list集合中的指定對象
c、替換
        voidfill(List<? super T> list, T obj);//將list集合中的全部元素替換成指定對象obj
        booleanreplaceAll(List<T> lsit,T oldVal,T newVal);//用newVal替換集合中的oldVal值
        void swap(Listlist,int i,int j);/在指定列表的指定位置處交換元素
        void shuffle(List<?> list);//使用默認隨機源對list集合中的元素進行置換
d、反轉
        reverse(List<?> list);//反轉list集合中元素的順序
        Comparator reverseOrder();//返回一個比較器,強行逆轉了實現Comparable接口的對象的自然順序
        ComparatorreverseOrder(Comparator<T> cmp);//返回一個比較器,強行逆轉了指定比較器的順序
e、同步的集合
        List<T>synchronizedList(List<T> list);//返回支持的同步(線程安全的)List集合
        Map<K,V>synchronizedList(Map<K,V> m);//返回支持的同步(線程安全的)Map集合
 
代碼示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class  CollectionsDemo
{
	public static void main(String[] args) 
	{
		List<String> list = new ArrayList<String>();
		list.add("abcd");
		list.add("aaa");
		list.add("z");
		list.add("kkkkkk");
		list.add("qq");
		list.add("cc");
		
		sop(list);
		//元素自身比較性排序
		Collections.sort(list);
		sop(list);
		
		String max = Collections.max(list);
		sop("max="+max);
 
		int index = Collections.binarySearch(list,"aaa");
		sop("''aaa'':index="+index);
		index = Collections.binarySearch(list,"aaaa");
		sop("''aaaa'':index="+index);
				
		sop("------------------------------------------------");
		//比較器排序
		Collections.sort(list,new StuLenComparator());
		sop(list);
 
		max = Collections.max(list,new StuLenComparator());
		sop("max="+max);
 
		index = Collections.binarySearch(list,"aaa",new StuLenComparator());
		sop("''aaa'':index="+index);
 
		sop("------------------------------------------------");
		
		Collections.reverse(list);
		sop(list);
		Collections.replaceAll(list,"z","fff");
		sop(list);
		Collections.fill(list,"shasha");
		sop(list);
	}
	//二分法原理
	public static int halfSearch(List<String> list,String key)//,Comparator<String> cmp)
	{
		int max,min,mid;
		max = list.size()-1;
		min = 0;
		while(min<=max)
		{
			mid = (max+min)>>1;
			String str = list.get(mid);
			int num = str.compareTo(key);//cmp.compare(str,key);
			if(num>0)
				max = mid - 1;
			else if (num<0)
				min = mid + 1;
			else
				return mid;	
		}
		return -min-1;
	}
 
 
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
 
class StuLenComparator implements Comparator<String>
{
	public int compare(String s1,String s2)
	{
		if (s1.length()>s2.length())
			return 1;
		if (s1.length()<s2.length())
			return -1;
		return s1.compareTo(s2);
	}
}</span>
運行結果:
uploading.4e448015.gif轉存失敗重新上傳取消
 
三、Arrays
 
1、概述
     Arrays是用於操作數組的工具類。裏邊的方法也全是靜態的。不需要創建對象。

2、常見操作

數組變集合
Lsit<T> asList(T... a);//將數組轉換爲集合
把數組變成List集合的好處:可以使用集合的思想和方法來操作數組中的元素。如:contains,get,indexOf,subList等方法。
注意:
        a、將數組轉換成集合,不可使用集合的增刪方法,因爲數組的長度是固定的。如果進行增刪操作,則會產生UnsupportedOperationException的編譯異常。
        b、如果數組中的元素都是對象,則變成集合時,數組中的元素就直接轉爲集合中的元素。
        c、如果數組中的元素都是基本數據類型,那麼會將該數組作爲集合中的元素存在。
 
集合變數組
        Collection接口中的toArray方法。
        <T> T[]toArray(T[] a);將集合變爲指定類型的數組。
a、指定類型的數組到底要定義多長呢?
當指定類型的數組長度小於了集合的size,那麼該方法內部會創建一個新的數組。長度爲集合的size。
        當指定類型的數組長度大於了集合的size,就不會新創建了數組。而是使用傳遞進來的數組。
        所以創建一個剛剛好的數組最優。
b、爲什麼要將集合變數組?
爲了限定對元素的操作。不需要進行增刪了。
 
代碼示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class ArraysDemo 
{
	public static void main(String[] args) 
	{
		//將數組轉換爲集合
		sop("數組變集合-----------------");
		int[] arr = {2,5,9};
		sop(Arrays.toString(arr));
 
		String[] str = {"abc","cc","kkkkk"};
		List<String> list = Arrays.asList(str);
		sop(list);
		sop("contains:"+list.contains("cc"));
		//list.add("uu");//UnsupportedOperationException
 
		List<int[]> li = Arrays.asList(arr);
		sop(li);
		
		Integer[] num = {2,5,9};
		List lis = Arrays.asList(num);
		sop(lis);
 
		//集合變數組
		sop("集合變數組-----------------");
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
 
		String[] s = al.toArray(new String[al.size()]);
		sop(Arrays.toString(s));
		s = al.toArray(new String[5]);
		sop(Arrays.toString(s));
 
	}
 
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}</span>
運行結果:
uploading.4e448015.gif轉存失敗重新上傳取消
 
四、增強for循環

1、格式:
        for(數據類型  變量名 :被遍歷的集合(collection)或者數組)
        {
            執行語句
        }
2、注意:
        a、對集合進行遍歷。只能獲取集合元素。但是不能對集合進行操作。可以看作是迭代器的簡寫形式。
        b、迭代器除了遍歷,還可以進行remove集合中元素的動作。如果使用ListIterator,還可以在遍歷過程中對集合進行增刪改查的操作。
3、傳統for和高級for的區別:
高級for有一個侷限性。必須有被遍歷的目標(集合或數組)。
建議在遍歷數組的時候,還是希望使用傳統for。因爲傳統for可以定義腳標。
代碼示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class ForEachDemo 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
 
		for(String s : al)
			System.out.println(s);
 
		int[] arr = {3,5,8};
		for(int i : arr)
			System.out.println(i);
 
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(1,"a");
		hm.put(2,"b");
		hm.put(3,"c");
		
		for(Integer i : hm.keySet())
			System.out.println(i+"---"+hm.get(i));
		
		for(Map.Entry<Integer,String> me : hm.entrySet())
			System.out.println(me.getKey()+"..."+me.getValue());
	}
}</span>
運行結果:
uploading.4e448015.gif轉存失敗重新上傳取消
 
五、可變參數
    如果一個方法在參數列表中傳入多個參數,個數不確定,那麼每次都要複寫該方法。這時可以用數組作爲形式參數。但是在傳入時,每次都需要定義一個數組對象,作爲實際參數。在JDK1.5版本後,就提供了一個新特性:可變參數。
    可變參數其實就是數組參數的簡寫形式。不用每一次都手動的建立數組對象。只要將要操作的元素作爲參數傳遞即可。隱式將這些參數封裝成了數組。
    在使用時注意:可變參數一定要定義在參數列表的最後面。
 
 
六、靜態導入
 
1、格式:
        import  static  java.util.Arrays.*;//導入的是Arrays這個類中的所有靜態成員。
        import  static  java.lang.System.*//導入了Ssytem類中所有靜態成員。
       沒加static導入的是類,加上static導入的全是某一個類中所有的靜態成員。這樣寫在調用該類的靜態方法時可以不用再寫類名。如:Arrays.sort(數組);就可以直接寫sort(數組);

2、注意:
       當類名重名時,需要指定具體的包名。當方法重名時,需要指定具體所屬的對象或者類。
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章