对Java来说:
==和=
==运算符的含义永远是判断两个变量(常量也是一种特殊变量)的值是否相等。
这里值的含义是:(=运算符进行的操作就是赋值)
- 基本数据类型:值就是其值本身;
- 引用数据类型的值就是其引用的对象的地址;
equals()和hashcode():
这是两个从java.lang.Object对象继承的可重写的方法。
public class Object {
public boolean equals(Object obj) {
return (this == obj);
}
public native int hashCode(); //native说明是用其他语言实现的,返回对象在内存中的地址
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
...
}
根据规定:
x.hashcode() == y.hashcode()
的值应与 x.equals(y)
值一样。也就是说由x.equals(y)
值应能 => x.hashcode() == y.hashcode()
值
(但是规定并不要求x.hashcode() == y.hashcode()
可以 => x.equals(y)
值)
在重写方法的时候要遵循这一规定。
以下描述中对象x和y相等的含义为x.equals(y) == true
Set容器中对象不能相等(Set的add方法会保证),但是对象的hashcode不一定不同。
HashSet为了提高对象比较效率,判断两个对象是否相等的实现是先判断两个对象的hashcode,若不同则认为两个对象不相等,若相同则再调用equals方法判断两个对象是否真正的相等。
看以下程序:
public class Test {
@Override
public boolean equals(Object obj) {
return true;
}
public static void main(String[] args) {
HashSet<Test> h = new HashSet<Test>();
Test t1 = new Test();
Test t2 = new Test();
h.add(t1);
h.add(t2);
System.out.println(h.size()); //输出2
}
}
h.size()为2说明HashSet把两个相等的对象判别为不相等。原因是我们在重写equals方法时没有遵守规定;
对于java.lang.String类,equals方法返回两个字符串的字符序列是否相同:
public static void main(String[] args) {
String s1 = new String("123");
String s2 = new String("123");
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s2); //false
}
对null的处理:
equals有以下规定:
对于任何非空引用值 x,x.equals(null)
都应返回 false。
另外看下面程序运行结果:
public static void main(String[] args) {
HashSet<Test> set = new HashSet<Test>();
Map<Object, Object> map = new HashMap<Object, Object>();
set.add(null);
System.out.println(set.contains(null)); //true
map.put("1", null);
map.put(null, 1);
System.out.println(map); //{null=1, 1=null}
System.out.println(map.get(1)); //null
System.out.println(map.get("1")); //null
System.out.println(map.get(null)); //1
}