答案是不一样的。
HashSet与HasMap在添加新对象是,会先判断容器中是否已存在相等的对象(比较key是否相等),如果存在,HashSet的处理方式是放弃存储新对象,然而HashMap的处理方式是覆盖之前的对象。
相等对象:如果两个引用指向同一个对象,那么这两个引用是相等的,他们的hashcode方法返回的值一致。如果没有重写Object中hashcode方法,返回的是对象在内存中的地址(值中带有‘@’)。所以必须要要重写hashCode()方法,才能使得两个对象都有相同的hashCode,并且还要重写equals()方法使得返回的值为true。满足这两个条件,那么证明两个对象在HashMap/HashSet中是相等的。
用一段测试代码来展示:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import lombok.Data;
public class TestHashSetAndHashMap {
@Data
public static class Person {
private Integer id;
private String name;
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Person(){}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(id, person.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
public static void main(String[] args) {
Person p1 = new Person(1,"zhangshan");
Person p2 = new Person(1, "Lisi");
Set<Person> set = new HashSet<>();
set.add(p1);
for (Person p : set) {
System.out.println(p.getName());
}
set.add(p2);
for (Person p : set) {
System.out.println(p.getName());
}
//HashMap是覆盖
Map<Integer, Person> map = new HashMap<>();
map.put(p1.getId(), p1);
for (Map.Entry e : map.entrySet()) {
System.out.println(e.getValue());
}
map.put(p2.getId(), p2);
for (Map.Entry e : map.entrySet()) {
System.out.println(e.getValue());
}
}
}
结果:
32
32
zhangshan
zhangshan
TestHashSetAndHashMap.Person(id=1, name=zhangshan)
TestHashSetAndHashMap.Person(id=1, name=Lisi)
可以看出HashSet放弃存储新对象,HashMap直接覆盖原有对象。