Java 手册
equals
public boolean equals(Object obj)
- 指示其他某个对象是否与此对象“相等”。
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
。
Object
类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值x
和y
,当且仅当x
和y
引用同一个对象时,此方法才返回true
(x == y
具有值true
)。注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
- 自反性:对于任何非空引用值
- 参数:
obj
- 要与之比较的引用对象。- 返回:
- 如果此对象与 obj 参数相同,则返回
true
;否则返回false
。 - 另请参见:
hashCode()
,Hashtable
二者简单比较
== 比较的是地址,是栈里面的内容,地址信息都是存放在栈内存里面的。
equals 比较的是值,对象的值都是存放在堆内存里面的。
简单实例:
Integer a1 = new Integer(456); //实例化一个对象 Integer a2 = new Integer(456); //实例化一个对象 System.out.println(a1.equals(a2)); //这里比较的是值,都是456,结果是true System.out.println(a1==a2); //这里比较的是地址,因为是2个对象,所以地址不同,是false
注:Integer是属于包装类里面的引用类型。
equals 方法重写
系统会给定一个 equals()方法,
但是,一般equals()方法都是自己重写的,所以要明白equals()方法里面的详细架构。
@Override public boolean equals(Object obj) { // 判断地址是否一致,如果地址相同,那么对象的值一定相同 if (this == obj) return true; // 判断参数是否为空,如果传进来的参数是空,那肯定不相等 if (obj == null) return false; // 判断类型是否一致,如果类型不一致,那么对象里面的值根本没有可比性 if (this.getClass() != obj.getClass()) return false; // 判断属性是否一致 User user = (User) obj; if (this.username == null) { if (user.username != null) return false; } else if (!this.username.equals(user.username)) return false; if (this.password == null) { if (user.password != null) return false; } else if (!this.password.equals(user.password)) return false; return true; }
注:
username 和 password 两个参数都是自己定义的,其它代码都是自动生成的。
User user = (User) obj;是根据代码中 username 和 password 两个成员变量所在的类生成的,
在这里创建一个对象是为了判断这两个成员变量的栈地址是否相同。
下面是系统给的默认equals()方法,如果自己没有重写方法,那么系统会默认调用默认方法。
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
完整的实例代码:
package cn.tedu.object; public class ObjectExer { } class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } // hashCode的重写: // 如果两个对象equals为true,那么哈希码一致 // 不同对象的哈希码要不同并且要做到散列分布 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (password == null) { if (other.password != null) return false; } else if (!password.equals(other.password)) return false; if (username == null) { if (other.username != null) return false; } else if (!username.equals(other.username)) return false; return true; } }