很多时候我们都需要对两个变量进行比较,判断它们是否相等。不用性质的变量的比较方法会有所不同,其比较的含义也不尽相同,本文将讨论一下基本数据类型变量、引用变量和对象变量的比较方法和意义。
一、primitive基本数据类型比较
用==比较基本数据类型的变量,当变量的值相等时,则认为这两个变量相等。即使是不同类型的变量,只要它们的值相等,就认为它们相等。
二、引用比较
用==比较两个引用是否指向堆上的同一个对象。其实引用也是个变量值,只是这个值是取得特定对象的位表示法,可以类比成这个对象的访问地址。用==比较两个引用其实就是判断这两个引用是不是指向内存里的同一个东西。
三、对象的比较
用equals()方法比较两个对象在某种意义上是否相等。在没有重写equals()方法的默认情况下,比较的依然是这两个对象是不是堆上的同一个对象。
但很多情况下,我们是想比较两个对象是否具有相同的属性,而就此判断它们是不是相等,此时就需要重写equals()方法。
至此,对象的比较已基本完成。但是,我们需要注意到:如果以我们重写的规则来判断两个对象是相等的,那么这两个对象就应该满足某些操作规则,例如在HashSet中就不应该出现两个重复的对象,而HashSet判断两个对象是否重复不仅需要调用equals()方法,同时还会调用hashCode()方法以判断两个对象的HashCode是否相等。因此,我们在重写了equals()方法同时,也应该重写hashCode()方法,以使得相等的两个对象具有相同的HashCode。
HashCode是对象的int型的散列码,用于支持哈希机制的集合类操作,通常是根据对象的地址或字符或数值计算得到的,大多数情况下不同对象的HashCode是不相等的,但也有巧合的情况是相等的,此时就不能直接认为两个对象也相等。
结论:(1)重新了equals()方法的同时也应该重新hashCode()方法,即符合“相等的两个对象具有相同的HashCode”;(2)HashCode相等并不意味着两个对象是相等。
一、primitive基本数据类型比较
用==比较基本数据类型的变量,当变量的值相等时,则认为这两个变量相等。即使是不同类型的变量,只要它们的值相等,就认为它们相等。
int a = 1;
int b = 2;
float c = 1.0f;
boolean result1 = (a == b);//false
boolean result2 = (a == c);//true
二、引用比较
用==比较两个引用是否指向堆上的同一个对象。其实引用也是个变量值,只是这个值是取得特定对象的位表示法,可以类比成这个对象的访问地址。用==比较两个引用其实就是判断这两个引用是不是指向内存里的同一个东西。
public class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Person p1 = new Person("p1",20);
Person p2 = new Person("p1",20);
Person p3 = p1;
boolean result3 = (p1 == p2);//false
boolean result4 = (p1 == p3);//true
三、对象的比较
用equals()方法比较两个对象在某种意义上是否相等。在没有重写equals()方法的默认情况下,比较的依然是这两个对象是不是堆上的同一个对象。
Person p1 = new Person("p1",20);
Person p2 = new Person("p1",20);
Person p3 = p1;
boolean result5 = (p1.equals(p2));//false
boolean result6 = (p1.equals(p3));//true
但很多情况下,我们是想比较两个对象是否具有相同的属性,而就此判断它们是不是相等,此时就需要重写equals()方法。
@Override
public boolean equals(Object obj) {
if(obj == null){
return false;//1
}
if(this == obj){
return true;//2
}
if(obj instanceof Person){
Person temp = (Person)obj;
if(this.name.equals(temp.getName()) && this.age == temp.age){
return true;//3
}else {
return false;//4
}
}else {
return false;//5
}
}
Person p1 = new Person("p1",20);
Person p2 = new Person("p1",20);
Person p3 = p1;
Person p4 = new Person("p4",20);
boolean result7 = (p1.equals(null));//false,在1处返回
boolean result8 = (p1.equals(p3));//true,在2处返回
boolean result9 = (p1.equals(p2));//true,在3处返回
boolean result10 = (p1.equals(p4));//false,在4处返回
boolean result11 = (p1.equals(new Integer(1)));//false,在5处返回
至此,对象的比较已基本完成。但是,我们需要注意到:如果以我们重写的规则来判断两个对象是相等的,那么这两个对象就应该满足某些操作规则,例如在HashSet中就不应该出现两个重复的对象,而HashSet判断两个对象是否重复不仅需要调用equals()方法,同时还会调用hashCode()方法以判断两个对象的HashCode是否相等。因此,我们在重写了equals()方法同时,也应该重写hashCode()方法,以使得相等的两个对象具有相同的HashCode。
@Override
public int hashCode() {
TODO: 重新计算HashCode,使得满足equals()方法的对象拥有相等的哈希值
//简单的测试例子:
return this.name.length() + this.age;
}
HashCode是对象的int型的散列码,用于支持哈希机制的集合类操作,通常是根据对象的地址或字符或数值计算得到的,大多数情况下不同对象的HashCode是不相等的,但也有巧合的情况是相等的,此时就不能直接认为两个对象也相等。
结论:(1)重新了equals()方法的同时也应该重新hashCode()方法,即符合“相等的两个对象具有相同的HashCode”;(2)HashCode相等并不意味着两个对象是相等。