在Java中使用带有String和Object的equals()方法
Object o1 = new Object(); Object o2 = new Object(); //o1=o2; System.out.println(o1.equals(o2));
它返回false
。 如果删除注释,它可以返回true
。
为什么不适用于String
类?
String s1=new String(); String s2=new String(); System.out.println(s1.equals(s2));
它返回true
。 为什么? (因为String
使用实习或其他涉及的东西?)
因为String的equals()比较内容,而不是对象本身。
public boolean equals(Object anObject)
将此字符串与指定的对象进行比较。 当且仅当参数不为null并且是表示与此对象相同的字符序列的
String
对象时,结果才为真。
/* String.equals() */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
(链接到String.equals()的源代码)
与对象相等 :
类
Object
的equals方法实现了Object
上最具辨别力的等价关系; 也就是说,对于任何非空引用值x
和y
,当且仅当x
和y
引用同一对象时,此方法才返回true(x == y
的值为true
)。
/* Object.equals() */ public boolean equals(Object obj) { return (this == obj); }
(链接到Object.equals()的源代码)
另外,不要忘记equals()
函数的契约:
equals方法在非null对象引用上实现等价关系:
- 它是自反的 :对于任何非空引用值
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.hashCode()
- 有效的Java(布洛赫)
equals
for Object
比较内存引用。
这就是为什么它是错误的,因为它们是不同的Object
重写String
equals
基于字符进行比较。
你有2个空的String
对象,这就是equals
返回true
。
==
比较对象/字符串/任何东西的地址
.equals()
旨在使用对象的内部状态进行比较。
所以:
new Object() == new Object() => false
– 内存中不同地址的两个独立对象。
new String("a") == new String("a") => false
– 相同的情况 – 字符串对象的两个单独地址。
new String("a").equals(new String("a")) => true
– 地址不同,但Java将采用一个对象状态(’a’)并与其他对象状态(’a’)进行比较他们平等,并将报告真实。
使用equals()方法,您可以以任何适合您的程序的方式编写比较代码。
intern()
是一个有点不同的故事。 它旨在为相同的char序列返回相同的对象(地址)。 当您多次构造相同的字符串时,减少所需的内存量非常有用。
new String("aaa").intern()
将在机器内存中查找是否有人在之前创建了“aaa”字符串并将返回字符串的第一个实例…如果找不到,则将使用当前的实例作为第一个和所有进一步的“aaa”.intern()和新的String("aaa").intern()
和("a"+"aa").intern()
将返回该“第一个”实例。
注意: "aaa".intern()
操作速度不是很快,如果你将实习所有的字符串 – 你将节省一些内存,但会耗费相当多的CPU工作。
Object
类中实现的equals
仅比较引用。 这是源代码:
public boolean equals(Object obj) { return (this == obj); }
如果你想让它以某种其他方式运行,则需要在类中重写equals方法。 默认情况下,它会检查两个引用是否引用同一对象。
Object
类的equals()
方法不知道如何比较Strings,它只知道如何比较对象。 为了比较字符串,字符串类将覆盖equals()
方法并比较其中的字符串。
Object.equals()
将仅比较引用,其中String.equals()
将比较值。