equals
equals方法来自于object类, equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
equals 方法在非空对象引用上实现相等关系:
- 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
- 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
- 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
- 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
- 对于任何非空引用值 x,x.equals(null) 都应返回 false。
//equals在java中的底层实现(源码)
public boolean equals(Object obj) {
return (this == obj);
}
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
hashCode方法简介:同equals方法相同,来源于Object类。
hashCode返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的。)
hashCode 的常规协定是:
- 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
- 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
- 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
"=="与equals的区别:
//例一:
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2);//true
System.out.println(str1.equals(str2));//true
}
上述代码在内存中的存储过程
str1和str2两个变量同时指向存储于常量池中的"abc’'常量,所以"str1==str2"结果为true,str1.equals(str2)是对比两个变量的之,因此,结果也为true。
//例二:
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2);//true
System.out.println(str1.equals(str2));//true
String str3 = new String("abc");
System.out.println(str1 == str3);//false
System.out.println(str1.equals(str3));//true
String str4 = new String("abc");
System.out.println(str3 == str4);//false
System.out.println(str3.equals(str4));//true
}
上述代码在内存中的存储过程
两条 new 语句创建了两个对象,然后用 str3,str4这两个变量分别指向了其中一个对象,这是两 个不同的对象,它们的首地址是不同的,即 str3和 str4中存储的数值是不相同的,所以,表达 式 str3==str4 将返回 false,而这两个对象中的内容是相同的,所以,表达式 srt3.equals(str4)将返回 true。
结论:
由此可见,"=="操作符专门用来比较两个变量的值是否相等,
也就是用于比较变量所对应的内存中所存储的数值是否相同,
要比较两个基本类型的数据或两个引用变量是否相等,只能用"=="操作符。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,
对象本身占用一块内存(堆内存),变量也占用一块内存,
例如 Objet obj = new Object();变量 obj 是一个内存, new Object()是另一个内存,
此时,变量 obj 所对应的内存中存储的数值就是对象占用的那 块内存的首地址。
对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,
即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals 方法是用于比较两个独立对象的内容是否相同。
如果一个类没有自己定义 equals 方法,它默认的 equals 方法(从 Object类继承 的)就是使用 = = 操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用 equals 和使用 = = 会得到同样的结果,如果比较的是两个独立的对象则总返回 false。如果你 编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖 equals 方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。