前言:我们知道Set中所存储的元素是不重复的,那么Set接口的实现类HashSet在添加元素时是怎么避免重复的呢?
HashSet在添加元素时,是如何判断元素重复的?
● 在底层会先调用hashCode(),注意,Object中的hashCode()返回的是对象的地址,此时并不会调用;此时调用的是类中重写的hashCode(),返回的是根据内容计算的哈希值,遍历时,会用哈希值先比较是否相等,会提高比较的效率;但哈希值会存在问题:内容不同,哈希值相同;这种情况下再调equals比较内容,这样既保证效率又确保安全。
案例:
● 这是错误写法,此时默认调用的是Object类中hashCode( ),返回对象地址
import java.util.HashSet;
import java.util.Objects;public class Student {private String name ;private String num;public Student(String name, String num) {this.name = name;this.num = num;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", num='" + num + '\'' +'}';}public static void main(String[] args) {HashSet<Student> set = new HashSet<>();Student s1 = new Student("小王1","10001");Student s2 = new Student("小王2","10002");Student s3 = new Student("小王3","10003");Student s4 = new Student("小王1","10001");set.add(s1);set.add(s2);set.add(s3);set.add(s4);System.out.println(set);}}
此时之所以出现重复,因为默认调用的是Object类中hashCode( ),返回对象地址,s1和s4内容虽然相同,但作为两个对象,地址肯定不同。 | 注意: HashSet: 元素是无序的.
● 正确写法应该是,在Student类中重写hashCode()和equals()
package Demo;import java.util.HashSet;
import java.util.Objects;public class Student {private String name ;private String num;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return num.equals(student.num);}@Overridepublic int hashCode() {return Objects.hash(num);}public Student(String name, String num) {this.name = name;this.num = num;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", num='" + num + '\'' +'}';}public static void main(String[] args) {HashSet<Student> set = new HashSet<>();Student s1 = new Student("小王1","10001");Student s2 = new Student("小王2","10002");Student s3 = new Student("小王3","10003");Student s4 = new Student("小王1","10001");set.add(s1);set.add(s2);set.add(s3);set.add(s4);System.out.println(set);}}
这样就能避免重复了(此图是s1,s4重复,但只输出s1)| 注意:HashSet: 元素是无序的
● 补充:如何快速生成hashCode()和equals()的重写方法?
右键选择Generate,选择equals()and hashCode(),选择重写的属性。