Set集合
-
HashSet的2中遍歷方式
-
執行路口
package cn.xiaoge.day14.demo02; /* java.util.Set接口 extends Collection接口 Set接口的特點: 1. 不允許存儲重複的元素 2. 沒有索引, 沒有帶索引的方法, 也不能使用普通的for循環遍歷 java.util.HashSet集合 implements Set接口 HashSet特點: 1. 不允許存儲重複的元素 2. 沒有索引, 沒有帶索引的方法, 也不能使用普通的for循環遍歷 3. 是一個無序的集合, 存儲元素和取出元素的順序有可能不一致 4. 底層是一個哈希表結構(查詢的速度非常的塊) */ import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class Demo01Set { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); // 使用add方法往集合中添加元素 set.add(1); set.add(3); set.add(2); set.add(1); // 使用迭代器遍歷set集合 Iterator<Integer> it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); // 1, 2, 3 } System.out.println("==================="); // 使用增強for循環遍歷set集合 for (int num: set) { System.out.println(num); // 1, 2, 3 } } } // 運行結果 1 2 3 =================== 1 2 3
-
-
HashSet存儲不重複元素的原理
-
執行路口
package cn.xiaoge.day14.demo02; /* Set集合不允許存儲重複元素的原理 Set集合在調用add方法的時候, add方法會調用元素的hashCode方法和equals方法, 判斷元素是否重複. set.add(s1); add方法會調用hashCode方法, 計算字符串"abc"的哈希值, 哈希值是**96354**在集合中找有沒有**96354** 這個哈希值的元素, 發現**沒有**, **就會把s1存儲到集合中** set.add(s2); add方法會調用s2的hashCode方法, 計算字符串"abc"的哈希值, 哈希值是**96354**在集合中找有沒有**96354** 這個哈希值的元素, 發現**有(哈希衝突)**, s2會調用equals方法和哈希值相同的元素進行比較s2.equals(s1), 返回 **true**兩個元素的哈希值相同, equals方法返回true, 認定**兩個元素相同*, 就不會把s2存儲到集合中** set.add("重地"); set.add("通話"); 哈希值相同, 值不相同所以存儲 set.add("abc"); 哈希值相同, 值相同不存儲 */ import java.util.HashSet; public class Demo02HashSetSaveString { public static void main(String[] args) { // 創建HashSet集合對象 HashSet<String> set = new HashSet<>(); String s1 = new String("abc"); String s2 = new String("abc"); set.add(s1); set.add(s2); set.add("重地"); set.add("通話"); set.add("abc"); System.out.println(set); // [重地, 通話, abc] } } // 運行結果 [重地, 通話, abc]
-
-
哈希值
-
Person類
package cn.xiaoge.day14.demo03; public class Person extends Object { // 重寫hashCode方法 @Override public int hashCode(){ return 1; } }
-
執行路口
package cn.xiaoge.day14.demo03; /* 哈希值: 是一個十進制的整數, 由系統隨機給出(就是對象的地址值, 是一個邏輯地址, 是模擬出來的地址, 不是數據實際存儲的物理地址) 在Object類有一個方法, 可以獲取對象的哈希值 int hashCode() 返回該對象的哈希碼值. hashCode方法的源碼: public native int hashCode(); native: 代表該方法調用的是本地操作系統的方法 */ public class Demo02HashCode { public static void main(String[] args) { // Person類繼承了Object類, 所以可以使用Object類的hashCode方法 Person p1 = new Person(); int h1 = p1.hashCode(); System.out.println(h1); // 1639705018 | 1(重寫後的值) System.out.println("==================="); Person p2 = new Person(); int h2 = p2.hashCode(); System.out.println(h2); // 1627674070 | 1(重寫後的值) System.out.println("==================="); /* toString方法的源碼: public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } */ System.out.println(p1); // cn.xiaoge.day14.demo03.Person@61bbe9ba System.out.println(p2); // cn.xiaoge.day14.demo03.Person@610455d6 System.out.println(p1==p2); // false System.out.println("==================="); /* String類的哈希值 String類重寫Object類的hashCode方法 */ String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.hashCode()); // 96354 System.out.println(s2.hashCode()); // 96354 System.out.println("==================="); // 他們兩個字符串雖然不同, 但是這兩個的哈希值確實是一樣的(哈希衝突) System.out.println("重地".hashCode()); // 1179395 System.out.println("通話".hashCode()); // 1179395 } } // 運行結果 1 =================== 1 =================== cn.xiaoge.day14.demo03.Person@1 cn.xiaoge.day14.demo03.Person@1 false =================== 96354 96354 =================== 1179395 1179395
-
-
HashSet存儲自定義元素
-
Person類
package cn.xiaoge.day14.demo02; import java.util.Objects; public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", 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; } }
-
執行路口
package cn.xiaoge.day14.demo02; /* HashSet存儲自定義類型元素 set集合保證元素唯一: 存儲的元素(String, Integer, ...Student, Person...), 必須重寫hashCode方法和equals方法 要求: 同名同年齡的人, 視爲同一個人, 只能存儲一次 */ import java.util.HashSet; public class Demo03HashSetSaveString { public static void main(String[] args) { // 創建HashSet集合存儲Person HashSet<Person> set = new HashSet<>(); Person p1 = new Person("小美女", 18); Person p2 = new Person("小美女", 18); Person p3 = new Person("小美女", 19); // 哈希值 System.out.println(p1.hashCode()); // 1639705018 | 從寫hashCode方法 734175839 System.out.println(p2.hashCode()); // 1627674070 | 從寫hashCode方法 734175839 System.out.println("========================"); // equals System.out.println(p1.equals(p2)); // false equals比較地址值, 因爲equals是Object類方法 | 從寫了equals方法 true set.add(p1); set.add(p2); set.add(p3); System.out.println(set); // [Person{name='小美女', age=18}, Person{name='小美女', age=18}, Person{name='小美女', age=19}] | [Person{name='小美女', age=19}, Person{name='小美女', age=18}] } } // 運行結果 734175839 734175839 ======================== true [Person{name='小美女', age=19}, Person{name='小美女', age=18}]
-
-
LinkedHashSet集合
-
執行路口
package cn.xiaoge.day14.Demo04; /* java.util.LinkedHashSet集合 extends HashSet集合 LinkedHashSet集合特點: 底層是一個哈希表(數組+鏈表/紅黑樹) + 鏈表: 多了一條鏈表(記錄元素的存儲順序), 保證元素有序 */ import java.util.HashSet; import java.util.LinkedHashSet; public class Demo04LinkedHashSet { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); set.add("www"); set.add("abc"); set.add("abc"); set.add("xiaoge"); System.out.println(set); // [abc, www, xiaoge] 無序, 不允許重複 System.out.println("===================================="); LinkedHashSet<String> linked = new LinkedHashSet<>(); linked.add("www"); linked.add("abc"); linked.add("abc"); linked.add("xiaoge"); System.out.println(linked); // [www, abc, xiaoge] 有序, 不允許重複 } } // 運行結果 [abc, www, xiaoge] ==================================== [www, abc, xiaoge]
-