集合之HashMap
HashMap是HashSet的底层,下面HashSet为例,说明重写equals和hashCode的重要性。
只重写equals
以下代码重写了equals:
package com.javalearn.map.hash;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class TestForHash {
public static void main(String[] args) {
Student s1 = new Student("zhang");
Student s2 = new Student("zhang");
System.out.println(s1.equals(s2)); // 未重写equals时,比较内存地址,返回false,重写后,比较内容,返回true
Set<Student> set = new HashSet<>();
set.add(s1);
set.add(s2);
System.out.println(set.size()); // set应该不可重复,s1和s2是相同的,却都能存进set中,这是因为他们的哈希值所映射到的底层数组下标不同,绕过了equals判断
}
}
class Student {
public String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass()!= obj.getClass()) return false;
Student student = (Student) obj;
return Objects.equals(name,student.name); // 调用了name的equals,从object到string,方法重写
}
}
输出结果:
true
2
重写equals和hashCode
以下代码重写了equals和hashCode:
package com.javalearn.map.hash;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class TestForHash {
public static void main(String[] args) {
Student s1 = new Student("zhang");
Student s2 = new Student("zhang");
System.out.println(s1.equals(s2)); // 未重写equals时,比较内存地址,返回false,重写后,比较内容,返回true
Set<Student> set = new HashSet<>();
set.add(s1);
set.add(s2);
System.out.println(set.size()); // 这时候只有1个元素,因为两者哈希值能被分配到同一个数组下标
}
}
class Student {
public String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass()!= obj.getClass()) return false;
Student student = (Student) obj;
return Objects.equals(name,student.name); // 调用了name的equals,从object到string,方法重写
}
@Override
public int hashCode() { // IDEA自带同时重写equals和hashCode的功能
return Objects.hash(name);
}
}
输出结果:
true
1