2010-01-06 87 views
20
StringBuffer sb1 = new StringBuffer("Java"); 
StringBuffer sb2 = new StringBuffer("Java"); 
System.out.println(sb1 == sb2); 
System.out.println(sb1.equals(sb2)); 

这里都返回false。这怎么可能?比较StringBuffer内容与等于

回答

27

equals方法StringBuffer不会从Object覆盖,所以它只是参考相等,即与使用==相同。我怀疑这样做的原因是StringBuffer是可修改的,并且覆盖equals对于您可能想要用作键的类似于类的类最为有用(尽管列表也有重载的equalsStringBuffer也是一种列表,所以这是有点不一致)。

18

您正在比较对StringBuffer对象的引用,而不是StringBuffer中的实际字符串。

System.out.println(sb1.toString().equals(sb2.toString()))会返回true,我认为这是您的预期或想要实现的。

2

StringBuffer似乎已经没有自己的equals方法,所以我的第一个猜想是,StringBuffer继承的Objectequals方法,其中比较了使用sb1 == sb2。因此,这两种方法都会产生相同的结果。

2

都比较对象的两个引用(sb1是1,sb2是第二个),因此两者都不相同。

如果您正在尝试比较内容 - 使用方法的compareTo(...)字符串类 - 那就是 - 使用方法的toString()首先得到字符串内容StringBuffer的的(.toString()。compareTo)。

Ps。从JDK 5开始,还有另一种速度更快的类,其行为完全如StringBuffer - 它是StringBuilder ,也是 ,但不是线程安全的。

StringBuffer sb1 = new StringBuffer("Java"); 
StringBuffer sb2 = new StringBuffer("Java"); 

System.out.println(sb1.toString().compareTo(sb2.toString())); 
+0

据我所知,StringBuidler不是线程安全的 – Yaneeve 2010-01-06 11:18:06

+0

StringBuilder不是线程安全的。从StringBuilder上的SDK文档:“与StringBuffer兼容,但**不保证同步**”,从以下的介绍段落开始:http://java.sun.com/j2se/1.5.0/docs/api/ java/lang/StringBuilder.html – 2010-01-06 11:26:17

+0

当然,我的不好。阅读StringBuffer的文档太快,IT由StringBuilder填充,因此它意味着供单个线程使用。对不起。 – mkolodziejski 2010-01-06 11:32:05

4

简单的答案是StringBuffer(和StringBuilder)不重新定义Object.equals()的基本语义。因此,StringBuffer上的equals将简单地比较对象引用。

事实上,字符串的StringBuffer,StringBuilder的和CharBuffer中都实现了CharSequence接口,并且该接口的Javadoc这样说:

此接口不修改的equals和hashCode方法的一般合同。因此,比较实现CharSequence的两个对象的结果通常是未定义的。每个对象都可以由不同的类来实现,并且不能保证每个类都能够测试其实例与其他实例的相等性。因此,将任意CharSequence实例用作集中的元素或映射中的键是不合适的。

0

想知道为什么StringBuffer不覆盖equals方法。可能是因为该对象的内容通过toString()方法获得,并且具有所需的方法。

5
1. System.out.println(sb1 == sb2); 

仅当StringBuffer对象与自身比较时,StringBuffer的equals方法才返回true。与任何其他StringBuffer相比,即使两者包含相同的字符,它也会返回false。

这是因为“==”检查引用平等,因为这两个SB1和SB2是不同的对象引用,所以如果你想检查的内容是在这种情况下,输出是“假的”

仍等于在这两个StringBuffer的对象,你可以使用这个:

sb1.toString().equals(sb2.toString()) 

2. System.out.println(sb1.equals(sb2)); 

这是给“假”输出,因为.equals()方法尚未在StringBuffer类覆盖。所以它使用父级“Object”类中的.equals()方法。在对象类中已经写入了.equals()以检查引用的相等性。

请注意,在String的情况下,sb3.equals(sb4)将返回“true”。因为.equals()方法已在String类中被覆盖,以检查和匹配两个不同的字符串的内容。

0

Stringbuffer的equals()未被覆盖。它不会比较值,它只会比较参考值分配。这就是为什么你会因为他们都指向不同的对象而变得虚假。