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]
-