Java學習:集合類2
Set
HashSet
特點:元素唯一,但是無序。
如何保證元素的唯一性的呢(分析源碼)?
通過簡單的分析,我們知道HashSet集合保證元素的唯一性和add()方法相關。
如何我們想深入的了解,就必須看add()方法的源碼,看它的底層依賴什麽內容?
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {...}
左邊:e.hash == hash
比較對象的哈希值。
右邊:((k = e.key) == key || key.equals(k))
左邊:(k = e.key) == key
比較對象的地址值。
右邊:key.equals(k)
比較的是對象的內容是否相同。默認情況下比較的是地址值
結論:
底層數據結構是哈希表。
哈希表依賴兩個方法:hashCode()和equals()
執行流程:
首先判斷哈希值是否相同,如果不同,就直接添加到集合。
如果相同,繼續執行equals(),看其返回值,
如果是false,就直接添加到集合。
如果是true,說明元素重復不添加。
使用:
如果你看到哈希結構的集合,就要考慮可能需要重寫這兩個方法。
如果真要重寫,自動生成即可。
HashSet練習代碼如下
1 //創建一個HashSet集合HashSet無序2 HashSet<String> set = new HashSet<String>(); 3 4 //給集合中添加元素 5 set.add("a"); 6 set.add("b"); 7 set.add("c"); 8 set.add("d"); 9 set.add("e"); 10 set.add("f"); 11 12 //遍歷集合 13 /** 14 * HashSet集合特點:15 * 1.元素無序 16 * 2.元素唯一 17 */ 18 for (String string : set) { 19 System.out.println(string); 20 }
TreeSet
元素順序:使用元素的自然順序對元素進行排序,或者根據創建 set時提供的 Comparator進行排序,
具體取決於使用的構造方法。
底層算法:二叉樹。
1 TreeSet<Integer> ts = new TreeSet<Integer>(); 2 3 //給集合中存儲元素 4 //(20,18,23,22,17,24,19,18,24) 5 ts.add(20); 6 ts.add(18); 7 ts.add(23); 8 ts.add(22); 9 ts.add(17); 10 ts.add(24); 11 ts.add(19); 12 ts.add(18); 13 ts.add(24); 14 15 //遍歷集合 16 for (Integer integer : ts) { 17 System.out.println(integer); 18 }TreeSet自然排序
構造方法:
TreeSet()
構造一個新的空 set,該 set 根據其元素的自然順序進行排序。
TreeSet(Comparator<? super E> comparator)
構造一個新的空 TreeSet,它根據指定比較器進行排序。
如果想使用自然排序的方法對對象進行排序,需要在對象類中重寫compareTo方法
重寫方法如下:
1 public int compareTo(Student s) { 2 //就是寫的是元素的比較規則,由你自己去動手寫出 3 //按照學生的年齡進行排序 4 /** 5 * 兩個對象進行比較: 6 * s 7 * this 8 */ 9 int num = this.age - s.age; 10 //判斷年齡是否相同,如果相同比較姓名 11 /** 12 * 寫這個比較規則的時候註意兩點: 13 * 1.他有主要條件,先按照主要條件進行排序 14 * 2.如果主要條件相同,就需要你自己分析出來他的次要條件,再去按照次要條件進行比較 15 */ 16 17 int num2 = num==0?this.name.compareTo(s.name):num; 18 return num2;對Student類中的CompareTo方法重寫
如果使用 set時提供的 Comparator進行排序,則需要創建一個Comparator接口的實現類對象。
案例如下:
1 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { 2 public int compare(Student s1, Student s2) { 3 int num = s1.getAge() - s2.getAge(); 4 int num2 = num==0?s1.getName().compareTo(s2.getName()):num; 5 return num2; 6 } 7 }); 8 9 //創建對象存入集合 10 Student s = new Student("guodegang", 50); 11 Student s6 = new Student("liuyifei", 50); 12 Student s2 = new Student("zhangxueyou", 55); 13 Student s3 = new Student("amu", 45); 14 Student s4 = new Student("tf-boys", 18); 15 Student s5 = new Student("wangfeng", 49); 16 17 ts.add(s); 18 ts.add(s2); 19 ts.add(s3); 20 ts.add(s4); 21 ts.add(s5); 22 ts.add(s6); 23 24 //遍歷集合 25 for (Student student : ts) { 26 System.out.println(student); 27 }按照指定規則排序
HashSet與TreeSet的相同點與不同點
相同點:
單列集合,元素不可重復
不同點:
1. 底層存儲的數據結構不同
HashSet底層用的是HashMap哈希表結構存儲,而TreeSet底層用的是二叉樹結構存儲
2.存儲時保證數據唯一性依據不同
HashSet是通過復寫hashCode()方法和equals()方法來保證的,而TreeSet通過Compareable接口的compareTo()方法來保證的
3.有序性不一樣
HashSet無序,TreeSet有序
Map
將鍵映射到值的對象。一個映射不能包含重復的鍵;每個鍵最多只能映射到一個值。
Map接口中的方法概述(創建集合測試方法):
A:刪除功能
void clear():移除集合中的所有鍵值對元素
V remove(Object key):根據鍵移除鍵值對元素,並返回值
B:判斷功能
boolean containsKey(Object key):判斷集合中是否包含指定的鍵
boolean containsValue(Object value):判斷集合中是否包含指定的值
boolean isEmpty():判斷集合是否為空
C:獲取功能
Set<Map.Entry<K,V>> entrySet():獲取鍵值對對象的集合,遍歷鍵值對對象,
利用getKey(),getValue()取出鍵和值
V get(Object key):根據鍵獲取值
Set<K> keySet():獲取所有的鍵
Collection<V> values():獲取所有的值
D:添加功能
V put(K key,V value):集合添加鍵值對
E:長度功能
int size():鍵值對對數。
HashMap
2.1元素順序:元素順序不可預測
2.2底層算法:哈希算法
2.3對鍵沒有要求(僅僅相對於TreeMap來說)
練習代碼如下:
1 //創建學生對象 2 Student s1 = new Student("傑克遜", 60); 3 Student s2 = new Student("孫楠", 50); 4 Student s3 = new Student("權誌龍", 30); 5 Student s4 = new Student("權誌龍", 30); 6 7 //將對象存入集合 8 hm.put(s1, "美國"); 9 hm.put(s2, "中國"); 10 hm.put(s3, "韓國"); 11 hm.put(s4, "中國"); 12 13 //遍歷集合 14 Set<Student> keys = hm.keySet(); 15 for (Student s : keys) { 16 System.out.println(s+" "+hm.get(s)); 17 }HashMap
Java學習:集合類2