Java語言:集合——Set、Map

Set接口概述:

           一個不包含重複元素的collection。
Collection
           
          List
                   有序(存儲順序和取出順序一致),可重複
          Set
                    無序(存儲順序和取出順序不一致),唯一
                    HashSet:它不保證Set的迭代順序;特別是它不保證順序恆久不變。
 

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo {
	public static void main(String[] args) {
		//創建集合
		Set<String> set = new HashSet<String>();
		
//		set.add("hello");
//		set.add("world");
//		set.add("java");
//		
//		//增強for
//		for(String s : set) {
//			System.out.println(s);
//		}
//		world
//		java
//		hello
		
		
		set.add("hello");
		set.add("world");
		set.add("java");
		set.add("world");
		set.add("java");
		
		//增強for
		for(String s : set) {
			System.out.println(s);
		}
//		world
//		java
//		hello

		
	}
}

HashSet:存儲字符串的唯一性

        查看add()方法源碼,方法底層依賴兩個方法:hashCode()和equals()。
        步驟:
               首先比較哈希值
               如果相同,繼續比較地址值或者equals()
               如果不同,就直接添加到集合中
        先看hashCode()值是否相同
               相同:繼續equals()方法。
                            返回true:說明元素重複,就不添加
                            返回false:說明元素不重複,就添加到集合
                不相同:就直接把元素添加到集合
         如果類沒有重寫這兩個方法,默認使用Object類中方法。一般不會相同。
         而String類重寫了hashCode()和equals()方法,所以,它就可以把內容相同的字符串去掉。保證唯一性。
                    

HashSet存儲自定義對象

        注意:需要重寫hashCode()方法和equals()方法(可自動生成)。優化hashCode()方法讓對象的哈希值儘可能的不同。(由於哈希值和對象的成員變量值相關,所以,最終解決方案就是把對象的成員變量值進行相加:如果是基本類型,就直接加值;如果是引用類型,就加哈希值)

public class Student {
	
	private String name;
	private int age;
	
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	
}

import java.util.HashSet;

public class HashSetDemo2 {
	public static void main(String[] args) {
		// 創建集合
		HashSet<Student> hashSet = new HashSet<Student>();

		// 創建學生對象
		Student s = new Student("劉備", 30);
		Student s2 = new Student("關羽", 27);
		Student s3 = new Student("張飛", 26);
		Student s4 = new Student("劉備", 30);
		Student s5 = new Student("關羽", 28);
		Student s6 = new Student("劉備", 27);
		Student s7 = new Student("張飛", 26);
		
		hashSet.add(s);
		hashSet.add(s2);
		hashSet.add(s3);
		hashSet.add(s4);
		hashSet.add(s5);
		hashSet.add(s6);
		hashSet.add(s7);
		
		for(Student ss : hashSet) {
			System.out.println(ss.getName()+"---"+ss.getAge());
		}
	}
}
----------------------------------------------------------------------
關羽---28
劉備---30
張飛---26
關羽---27
劉備---27

LinkedHashSet:底層數據結構由哈希表和鏈表組成。

          哈希表保證元素的唯一性。
          鏈表保證元素有序。(存儲和取出是一致)

TreeSet類概述:能夠對元素按照某種規則進行排序

           使用元素的自然順序對元素進行排序
           或者根據創建set時提供的Comparator(比較器)進行排序
           具體取決於使用的構造方法。

TreeSet集合的特點:排序和唯一

排序的真正比較是依賴與元素的compareTo()方法,而這個方法是定義在Comparable接口裏面的。所以,重寫該方法,必須實現實現Comparable接口。這個接口表示的就是自然排序。

TreeSet:底層是二叉樹結構。(紅黑樹是一種自平衡的二叉樹)
            元素存儲規則:
                         第一個元素存儲時,直接作爲根節點存儲。
                         從第二個元素開始,每個元素從根節點開始比較
                                         若大       作爲右孩子
                                         若小       作爲左孩子
                                         若相等      則不存儲
                          前序遍歷輸出,實現排序及唯一。

TreeSet存儲自定義對象並保證排序和唯一。自定義對象需要根據自定義對象的自然排序規則實現自然排序Comparable接口並重寫CompareTo()方法。

TreeSet集合保證元素排序和唯一性的原理
唯一性:是根據比較的返回是否是0來決定。
排序:
         A:自然排序(元素具備比較性)
                  讓元素所屬的類實現自然排序接口Comparable
         B:比較器排序(集合具備比較性)
                  讓集合的構造方法接收一個比較器接口的子類對象Comparator

public class Student implements Comparable<Student> {

	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int compareTo(Student s) {
		int num = this.age - s.age;
		int num2 = num == 0 ? this.name.compareTo(s.name) : num;
		return num2;
	}
}
import java.util.TreeSet;

public class TreeSetDemo {
	public static void main(String[] args) {
		
		TreeSet<Student> treeSet = new TreeSet<Student>();
		
		Student s = new Student("劉備", 30);
		Student s2 = new Student("關羽", 27);
		Student s3 = new Student("張飛", 26);
		Student s4 = new Student("劉備", 30);
		Student s5 = new Student("關羽", 28);
		Student s6 = new Student("劉備", 27);
		Student s7 = new Student("張飛", 26);
		treeSet.add(s);
		treeSet.add(s2);
		treeSet.add(s3);
		treeSet.add(s4);
		treeSet.add(s5);
		treeSet.add(s6);
		treeSet.add(s7);
		
		for(Student ss : treeSet) {
			System.out.println(ss.getName()+"---"+ss.getAge());
		}
	}
}
---------------------------------------------------------------------------------------------------
張飛---26
關羽---27
劉備---27
關羽---28
劉備---30

匿名內部類實現比較器排序。

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo {
	public static void main(String[] args) {
		
		TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				int num = s1.getAge() - s2.getAge();
				int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
				return num2;
			}
			
		});
		
		Student s = new Student("劉備", 30);
		Student s2 = new Student("關羽", 27);
		Student s3 = new Student("張飛", 26);
		Student s4 = new Student("劉備", 30);
		Student s5 = new Student("關羽", 28);
		Student s6 = new Student("劉備", 27);
		Student s7 = new Student("張飛", 26);
		treeSet.add(s);
		treeSet.add(s2);
		treeSet.add(s3);
		treeSet.add(s4);
		treeSet.add(s5);
		treeSet.add(s6);
		treeSet.add(s7);
		
		for(Student ss : treeSet) {
			System.out.println(ss.getName()+"---"+ss.getAge());
		}
	}
}


Map集合的特點:

       將鍵映射到值的對象。一個映射不能包含重複的鍵;每個鍵最多隻能映射到一個值。

Map集合和Collection集合的區別?

        Map集合存儲元素是成對出現的,Map集合的鍵是唯一的,值是可重複的。
       Collection集合存儲元素是單獨出現的,Collection的兒子Set是唯一的,List是可重複的。
       注意:
              Map集合的數據結構值針對鍵有效,跟值無關
              Collection集合的數據結構是針對元素有效

Map集合的功能概述:

       1、添加功能
                  V put(K key, V value):添加元素。
                           如果鍵是第一次存儲,就直接存儲元素,返回null
                           如果鍵不是第一次存在,就用值把以前的值替換掉,返回以前的值
       2、刪除功能
                  void clear():移除所有的鍵值對元素
                  V remove(Object key):根據鍵刪除鍵值對元素,並把值返回
       3、判斷功能
                  boolean containsKey(Object key):判斷集合是否包含指定的鍵
                  boolean containsValue(Object value):判斷集合是否包含指定的值
                  boolean isEmpty():判斷集合是否爲空
       4、獲取功能
                  Set<Map.Entry<K,V>> entrySet():返回的是鍵值對對象的集合
                  V get(Object key):根據鍵獲取值
                  Set<K> keySet():獲取集合中所有鍵的集合
                  Collection<V> values():獲取集合中所有值的集合
       5、長度功能
                  int size():返回集合中的鍵值對的對數
 


import java.util.HashMap;
import java.util.Map;
import java.util.Set;

//遍歷Map集合的兩種方法
public class HashMapDemo {
	public static void main(String[] args) {
		// 創建集合
		Map<String, String> map = new HashMap<String, String>();

		map.put("楊過", "小龍女");
		map.put("郭靖", "黃蓉");
		map.put("張無忌", "周芷若");
		map.put("梁山伯", "祝英臺");
		map.put("傑克", "露西");
		
		//獲取所有鍵的集合
		Set<String> set = map.keySet();
		
		//根據鍵獲取值進行遍歷
		for(String s : set) {
			System.out.println(s+"---"+map.get(s));
		}
		
		System.out.println("----------------------------");
		
		Set<Map.Entry<String, String>> set2 = map.entrySet();
		
		for(Map.Entry<String, String> map2 : set2) {
			System.out.println(map2.getKey()+"---"+map2.getValue());
		}
	}
}

HashMap類概述

        鍵是哈希表結構,可以保證鍵的唯一性

知識點:

       java中數值類型進製表示
            二進制:0b****;(*表示0或1)
            八進制:0****;(*表示0到7任意數字)
            十六進制:0x****;(*表示0到f任意數字)

LinkedHashMap:是Map接口的哈希表和鏈表實現,具有可預知的迭代順序。

          由哈希表保證鍵的唯一性
          由鏈表保證鍵盤的有序(存儲和取出的順序一致)

TreeMap類概述:

       鍵是紅黑樹結構,可以保證鍵的排序和唯一性。


 


//嵌套集合

/*
 * 升達
 *      cj   財經學院
 *                kj     會計專業
 *                      林黛玉      25
 *                      薛寶釵      28
 *                cwgl   財務管理
 *                      賈寶玉       26
 *                      王熙鳳       29
 *      xg   信工學院
 *                rjgc   軟件工程 
 *                      趙雲          26
 *                      馬超          27
 *                jk     計科專業
 *                      關羽          28
 *                      黃忠          30
 *      jg   建工學院
 *                tmgc   土木工程
 *                      宋江          37
 *                      李逵          32
 *                gcgl   工程管理
 *                      吳用          28
 *                      魯智深       33
 * 
 * 
 * */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class HashMapDemo2 {
	public static void main(String[] args) {
		// 創建升達集合
		HashMap<String, HashMap<String, ArrayList<Student>>> sdmap = new HashMap<String, HashMap<String, ArrayList<Student>>>();

		// 財經集合
		HashMap<String, ArrayList<Student>> cjmap = new HashMap<String, ArrayList<Student>>();
		// 會計集合
		ArrayList<Student> kjList = new ArrayList<Student>();
		Student s1 = new Student("林黛玉", 25);
		Student s2 = new Student("薛寶釵", 28);
		kjList.add(s1);
		kjList.add(s2);
		// 財務管理集合
		ArrayList<Student> cwglList = new ArrayList<Student>();
		Student s3 = new Student("賈寶玉", 26);
		Student s4 = new Student("王熙鳳", 29);
		cwglList.add(s3);
		cwglList.add(s4);
		cjmap.put("會計專業", kjList);
		cjmap.put("財務管理", cwglList);

		// 信工集合
		HashMap<String, ArrayList<Student>> xgmap = new HashMap<String, ArrayList<Student>>();
		// 軟工集合
		ArrayList<Student> rgList = new ArrayList<Student>();
		Student s5 = new Student("趙雲", 26);
		Student s6 = new Student("馬超", 27);
		rgList.add(s5);
		rgList.add(s6);
		// 計科集合
		ArrayList<Student> jkList = new ArrayList<Student>();
		Student s7 = new Student("關羽", 28);
		Student s8 = new Student("黃忠", 30);
		jkList.add(s7);
		jkList.add(s8);
		xgmap.put("軟件工程", rgList);
		xgmap.put("計科專業", jkList);
		
		// 建工集合
		HashMap<String, ArrayList<Student>> jgmap = new HashMap<String, ArrayList<Student>>();
		// 土木工程集合
		ArrayList<Student> tmList = new ArrayList<Student>();
		Student s9 = new Student("宋江", 37);
		Student s10 = new Student("李逵", 32);
		tmList.add(s9);
		tmList.add(s10);
		// 工程管理集合
		ArrayList<Student> gcList = new ArrayList<Student>();
		Student s11 = new Student("吳用", 28);
		Student s12 = new Student("魯智深", 33);
		gcList.add(s11);
		gcList.add(s12);
		jgmap.put("土木工程", tmList);
		jgmap.put("工程管理", gcList);
		
		sdmap.put("財經學院", cjmap);
		sdmap.put("信工學院", xgmap);
		sdmap.put("建工學院", jgmap);
		
		//遍歷集合
		Set<String> sdSet = sdmap.keySet();
		for(String sdKey : sdSet) {
			System.out.println(sdKey);
			HashMap<String,ArrayList<Student>> sdValue = sdmap.get(sdKey);
			Set<String> xySet = sdValue.keySet();
			for(String xyKey : xySet) {
				System.out.println("\t"+xyKey);
				ArrayList<Student> zyList = sdValue.get(xyKey);
				for(Student s : zyList) {
					System.out.println("\t\t"+s.getName()+"---"+s.getAge());
				}
			}
		}
	}
}
---------------------------------------------------------------------------------------------------------------
財經學院
	會計專業
		林黛玉---25
		薛寶釵---28
	財務管理
		賈寶玉---26
		王熙鳳---29
信工學院
	軟件工程
		趙雲---26
		馬超---27
	計科專業
		關羽---28
		黃忠---30
建工學院
	工程管理
		吳用---28
		魯智深---33
	土木工程
		宋江---37
		李逵---32


Hashtable和HashMap的區別?

          Hashtable:線程安全,效率低。不允許null鍵和null值
          HashMap:線程不安全,效率高。允許null鍵和null值

List,Set,Map等接口是否都繼承自Map接口?

            List,Set不是繼承自Map接口,它們繼承自Collection接口
            Map接口本身就是一個頂層接口

Collections類概述

         針對集合操作的工具類,都是靜態方法。

Collection和Collections的區別?

         Collection:是單列集合的頂層接口,有子接口List和Set。
         Collections:是針對集合操作的工具類,有對集合進行排序和二分查找的方法。

Collections類方法:

         public static <T> void sort(List<T> list):排序 默認情況下是自然排序。
         public static <T> int binarySearch(List<?> list,T key):二分查找
         public static <T> T max(Collection<?> coll):最大值
         public static void reverse(List<?> list):反轉
         public static void shuffle(List<?> list):隨機置換

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