总结下==和equals:
==比较的是变量的内容即对象地址,equals看情况。对于没有重写Object的equals方法的对象,和equals的效果是一样的都是比较地址,因为他们还是使用object的equals,而object的equals的作用和一眼,如果重写了object的eqals比较的就是内容了比如String类型,Integer类型,file类型,date类型。覆写了equals一般都要覆写hashcode()
Equlas和hashcode()在集合中体现:
在set集合中比如hashset中存对象是有规则的就是不能存同样的元素,
所以如何判断被存的元素有重合呢?他就是根据hashCode()方法和equals综合来判断的,先判断元素的hashcode,如果被存的元素的hashcode和集合中 任一个元素的hashcode不相同就存入,如果相同就再依据equals判断,如果通过equals判断还是相同就不存入,如果不相同尽管hashcode相同还是存入。这就验证了------- equals相同Hashcode就相同,但是hacode相同equals可能不相同。 这段话可以用下面的图表示:
Equals和hashcode()分别是两个方法,但他们都是用于比较用的,hashcode效率高,两个都是搭配使用
String Integer 的hashcode生成根据于内容,一般对象的hashcode生成根据于地址
在person类中重写hashcode,但是注释了equals
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person() {
}
public Person(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
return result;
}
/*@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
return true;
}*/
}
//测试类
public class Test{
public static void main(String[] args) {
Person p = new Person(2);
Person p1 = new Person(2);
System.out.println(p.hashCode());//33 System.out.println(p);//Test.Person@21
System.out.println(p1.hashCode());//33
System.out.println(p1);//Test.Person@21
Test.Person@21==包名+类名@+hachcode()的十六进制
System.out.println(p.equals(p1));//false
System.out.println(p==p1);//false
}
}
运行结果让我吃惊,hachcode和打印出来地址都相同,而==和equals比较却是false,为社么?
当我们覆写hashcode()时候,一旦创建对象,那么返回的hashcode就和覆写的有关了,和object的hashcode无关,当我们Person p = new Person(2);
Person p1 = new Person(2);
根据覆写的hashcode()方法,返回的就是p的hashcode是:311+2=33
P1的hashcode也是:311+2=33;
P和p1的hashcode都是33,而System.out.println(p1)打印出来的地址也不是大家所认为的实际地址,它是个根据实际地址通过hashcode()规则然后改编成的hash地址。
当p.equals(p1)
由于我把自定义的equals注释了,所以它就用object的equals方法比较,我们知道object的equals比较的就是对象的实际地址,和比较一样,大家可以查看源码,所以才为false
同样pp1也是比较实际地址,结果false.