文章目录
- “==”
- equals
- 对equals的重写
“==”
== :运算符 比较基本数据类型比的是数值(boolean数据不支持此运算),比较引用数据类型比的是地址值。
public static void main(String[] args) {
int a = 10;
int b = 10;
double c = 10;
char d = 10;
String str1= new String("不扰嶟");
String str2= new String("不扰嶟");
//基本数据类型的比较
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a == d);
//引用数据类型的比较
System.out.println(str1 == str2);
}
}
equals
equals:是定义在java.lang.Object下的方法,在没有重写的情况下,默认比的是两个对象的地址值,自然是比不了基本数据类型的。
public class Test {
public static void main(String[] args) {
String str1= new String("不扰嶟");
String str2= new String("不扰嶟");
A a = new A(10, "不扰嶟");
A b = new A(10, "不扰嶟");
System.out.println(str1.equals(str2));
System.out.println(a.equals(b));
}
}
class A {
private int a ;
private String b ;
public A(int a, String b) {
super();
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
运行结果:
说明:在这里第一个结果之所以是true是因为String类中已经对equals进行了重写,比较的是String类对象的值。代码如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
String、Date、File、包装类等都对equals进行了重写。
对equals的重写
由于java.lang.Object是所有类的父类,所以我们就可以重写equals方法,让其比较的不再是地址值,而是我们所关心的内容。
public class Test {
public static void main(String[] args) {
A a = new A(10, "不扰嶟");
A b = new A(10, "不扰嶟");
System.out.println(a.equals(b));
}
}
class A {
private int a ;
private String b ;
public A(int a, String b) {
super();
this.a = a;
this.b = b;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
return a == other.a && Objects.equals(b, other.b);
}
}
运行结果:
通常在重写equals()方法的时候,也会去重写hashCode()方法.
因为当我们把对象存入到底层为散列表结构的集合时,首先判断hashCode值,碰到相同的hashCode值之后再进行equals()进一步判断,这样保证如果两个对象是相等的,它们的equals()方法应该返回true,hashCode()也应该返回相同的结果。
遵守hashCode方法的常规约定。因为不能百分百确定这个类之后是否会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中用到,所以说重写equals()方法之后要尽量重写hashCode()方法。
注:hashCode方法的常规约定:
在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
a和b如果相等,则hashCode()的值一定相等。
a和b的hashCode()值相等,a和b不一定相等。