Java——HashSet存储元素不重复的原理?以及如何保证存储对象内容也不重复?

it2024-08-15  62

package com.zzfl.other; import java.util.HashSet; /* * 实时(现场)代码模板(Live Templates) * (1)psvm (2)sout (soutm、soutv、soutp、xxx.sout) * (3)fori (iter、数组或集合.fori)(4)inn (ifn 、xxx.nn、xxx.null) * (5)prsf:可生成 private static final * 类似的: * psf:可生成 public static final psfi:可生成 public static final int * psfs:可生成 public static final String * 快捷键 * ctrl+/ 单行注释 ctrl+shift+/ 多行注释 Ctrl+D 复制行 Ctrl+X 或 Ctrl+Y 删除行 * alt+enter 快速修正 alt+/ 代码补全 ctr+alt+L 格式化代码 ctr+shift+U 大小写转化 * Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如get,set方法,构造函数等) Ctrl+P 方法参数提示 * Ctrl+H 显示类结构图 Ctrl+Q 显示注释文档 CTRL+ALT+M 抽取方法 Shift+Enter,向下插入新行 Ctrl+Alt+Enter 向上插一行 * Ctrl+Shift+Up/Down代码向上/下移动。double shift 按两次shift键 全局搜索 * CTRL+ALT+T 把选中的代码放在 try{} if{} else{}里 Ctrl+鼠标点击 查看源码 * Shift+F6 文件重命名或者是变量重命名 Ctrl+Shift+T 为当前类设置单元测试 * Ctrl+shift+Enter 在小括号、方括号、大括号等输入完成之后自动跳出括号并且带上“;” * F8 单步跳过(step over); F7 单步进入(step into) Alt+Shift+F7 强制单步进入(force step into) * Shift+F8 单步退出(step out) F9 继续执行(resume program) * 面向对象的7大原则: * 1.开闭原则:面向扩展开放,面向修改关闭。 */ class Student { String name; Integer age; String sex; Double score; public Student() { } public Student(String name, Integer age, String sex, Double score) { this.name = name; this.age = age; this.sex = sex; this.score = score; } /* 重写hashCode()方法,定义内容相同的哈希码相同,内容不同的哈希码不同 */ @Override public int hashCode() { return this.name.hashCode()+this.age+this.sex.hashCode()+this.score.hashCode(); } //触发条件:两个对象的哈希码相同,才会触发equals()方法 @Override public boolean equals(Object obj) { if (this==obj) return true; if (obj==null) return false; if (this.getClass()!=obj.getClass()) return false; Student student = (Student)obj; if (this.name.equals(student.name) && this.age.equals(student.age) && this.score.equals(student.score )&& this.sex.equals(student.sex)) { return true; } return false; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + ", score=" + score + '}'+this.hashCode(); } } public class TestHashSet2 { public static void main(String[] args) { Student s1 = new Student("安琪拉", 20, "女", 90.5); Student s2 = new Student("关羽", 45, "男", 86.5); Student s3 = new Student("貂蝉", 19, "女", 88.6); Student s4 = new Student("赵云", 25, "男", 99.6); Student s5 = new Student("赵云", 25, "男", 99.6); HashSet<Student> students=new HashSet<>(); students.add(s1); students.add(s2); students.add(s3); students.add(s4); students.add(s1);//插入重复对象(地址重复) /* 地址不同,内容相同情况下还是会插入hashset集合当中,因为s4和s5 返回的哈希码是不同的,因此是不会除法equals进行二次比较的,此时就需要 重写hashCode()方法,来保证内容相同的返回相同哈希码,内容不同的 返回不同的哈希码。 */ students.add(s5);//插入重复对象(地址不同内容相同) for (Student student : students) { System.out.println(student); } } }

 

HashSet保证元素不重复是通过两部分实现的,第一步通过比较两个对象的哈希码是否相同如果相同,只能怀疑是相同对象,那么进而就会调用equals就行二次确认,如果确认完毕之后相同,那么就会排除第二个,否则的话就会插入该元素。因此,如果要保证存入对象的内容不同的时候就需要同时重写hash()和equals()方法自己定义比较的规则,一定要保证相同内容的对象的哈希码是相同的,不同对象的哈希码是不同的。

最新回复(0)