今天面试遇到的一个问题,总结如下
问:如果有一个HashMap它的key是一个对象,如何保证这个key的唯一性?
答:重写它的equals方法和hashcode方法
问:重写equals方法的同时一定要重写hashcode方法吗?
答:是的,因为HashMap在put元素的时候是先判断它的hashcode是否一样,若一样则调用equals比较,如果都一样才认为这个key已经存在
代码测试:
准备一个对象
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
p1和p2的属性值都是相同
Person p1 = new Person("小明", 12);
Person p2 = new Person("小明",12);
引用数据类型的比较需要重写equals方法,所以这里重写Person的equals方法
public class Person {
private String name;
private int age;
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);
}
}
测试
if (p1.equals(p2)) {
System.out.println("p1等于p2");
}
HashMap<Person, String> map = new HashMap<>();
map.put(p1,"小明p1");
map.put(p2,"小明p2");
map.forEach((person, s) -> System.out.println("key:"+person.toString()+";value:"+s));
很显然这里两个相同的key,却对应不同的value,这就与map中的key是唯一的相违背。
输出p1和p2的hashcode
System.out.println("p1.hashCode() = " + p1.hashCode());
System.out.println("p2.hashCode() = " + p2.hashCode());
很显然他们的hashcode是不相同的
这里再重写Person的hashcode方法
public class Person {
private String name;
private int age;
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);
}
}
重写hashcode方法后他们的hashcode相同
再尝试将p1和p2同时put进map中
HashMap<Person, String> map = new HashMap<>();
map.put(p1,"小明p1");
map.put(p2,"小明p2");
map.forEach((person, s) -> System.out.println("key:"+person.toString()+";value:"+s));
而此时map中只有小明p2
因为在同时添加p1和p2时间,map认为p1和p2是相等的,在加入p2时间已经有相同的key,而HashMap就会将相同key的value替换掉,而不再加入这个相同的key,这样就保证了key的唯一性
为什么在同时重写hashcode和equals方法后便可以保证HashMap中key的唯一性?
因为HashMap在put元素的时候是先判断它的hashcode是否一样,若一样则调用equals比较,如果都一样才认为这个key已经存在