1. ==和equals的区别
-
对于基本类型: ==比较的是两者的值,equals不适用
-
对于引用类型:==比较的是两者的地址,equals如果不重写,比较的也是地址;
int a = 2;
int b = 2;
//等于号比较的是地址
System.out.println("基本类型比较:" + (a == b)); // true
Person p1 = new Person();
p1.setId(1);
p1.setName(12);
Person p2 = new Person();
p2.setId(1);
p2.setName(12);
System.out.println("person比较==:" + (p1 == p2)); //false
//equals没有重写比较的是地址
System.out.println("person比较equals: " + (p1.equals(p2))); //重写为true,不重写为false
2.为什么equals重写之后比较的是内容呢?
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return id.equals(person.id) &&
name.equals(person.name); //Integer也重写了
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
3.为什么要重写hashCode()
如果你重写了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。
Person p1 = new Person();
p1.setId(1);
p1.setName(12);
Person p2 = new Person();
p2.setId(1);
p2.setName(12);
System.out.println("person比较equals: " + (p1.equals(p2))); //没有重写hashCode,但是还是true
这样,当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一个作为键值去查找他们的时候,则根本找不到。
HashMap<Person, Integer> map = new HashMap<>();
map.put(p1, 1);
map.put(p2, 1);
System.out.println("map的大小" + map.size()); //没有重写hashCode值是2,重写之后返回的是1,具体可看hashmap散列的映射。