Java 将 StringBuffer 内容与 equals 进行比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2012305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:31:07  来源:igfitidea点击:

Comparing StringBuffer content with equals

java

提问by GuruKulki

StringBuffer sb1 = new StringBuffer("Java");
StringBuffer sb2 = new StringBuffer("Java");
System.out.println(sb1 == sb2);
System.out.println(sb1.equals(sb2));

Here both are returning false. How is it possible?

这里两者都返回false。这怎么可能?

采纳答案by JaakkoK

The equalsmethod of StringBufferis not overridden from Object, so it is just reference equality, i.e., the same as using ==. I suspect the reason for this is that StringBufferis modifiable, and overriding equalsis mostly useful for value-like classes that you might want to use as keys (though lists also have an overridden equalsand StringBufferis kind of a list, so this is a bit inconsistent).

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

回答by Mark

You are comparing the references to the StringBuffer objects rather than the actual strings within the StringBuffer.

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

System.out.println(sb1.toString().equals(sb2.toString()))would return true and I assume this is what you had expected or wanted to achieve.

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

回答by Scharrels

StringBufferseems to have no equalsmethod of its own, so my first guess would be that StringBufferinherits the equalsmethod of Object, which compares using sb1 == sb2. Therefore, both methods yield the same result.

StringBuffer似乎没有equals自己的方法,所以我的第一个猜测是StringBuffer继承了 的equals方法Object,比较使用sb1 == sb2. 因此,这两种方法产生相同的结果。

回答by mkolodziejski

both compares two references to objects (sb1 is one, and sb2 is second), thus both are different.

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

If You are trying to compare content - use method compareTo(...)in Stringclass - that is - first get Stringcontent of StringBufferusing method toString()(.toString().compareTo).

如果您尝试比较内容 -在String类中使用方法compareTo(...)- 即 - 首先使用方法toString()( .toString().compareTo)获取StringBuffer 的字符串内容。

Ps. as of JDK 5, there is another much faster class that behaves exactly as StringBuffer- it is StringBuilder, and is alsobut is not thread safe.

附言。从 JDK 5 开始,还有另一个速度更快的类,其行为与StringBuffer完全相同——它是StringBuilder ,也是但不是线程安全的。

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

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

回答by Stephen C

The simple answer is that StringBuffer(and StringBuilder) do not override the base semantics of Object.equals(). So equalson a StringBufferwill simply compare object references.

简单的答案是StringBuffer(和StringBuilder)不会覆盖 的基本语义Object.equals()。所以equalson aStringBuffer将简单地比较对象引用。

In fact, String, StringBuffer, StringBuilderand CharBufferall implement the CharSequenceinterface, and the javadoc for this interface says this:

事实上, String, StringBuffer,StringBuilderCharBuffer都实现了CharSequence接口,这个接口的 javadoc 是这样说的:

This interface does not refine the general contracts of the equalsand hashCodemethods. The result of comparing two objects that implement CharSequenceis therefore, in general, undefined. Each object may be implemented by a different class, and there is no guarantee that each class will be capable of testing its instances for equality with those of the other. It is therefore inappropriate to use arbitrary CharSequenceinstances as elements in a set or as keys in a map.

这个接口没有细化equalshashCode方法的一般契约。因此,比较实现的两个对象的结果CharSequence通常是未定义的。每个对象可能由不同的类实现,并且不能保证每个类都能够测试其实例与另一个类的实例是否相等。因此,将任意CharSequence实例用作集合中的元素或映射中的键是不合适的。

Also note that javadocs for StringBuffer(and StringBuilder) explicitly states this:

另请注意,StringBuffer(和StringBuilder)的javadocs明确说明了这一点:

API Note:

StringBufferimplements Comparablebut does not override equals.Thus, the natural ordering of StringBufferis inconsistent with equals. Care should be exercised if StringBufferobjects are used as keys in a SortedMapor elements in a SortedSet.

API注意事项:

StringBuffer实现Comparable但不覆盖equals. 因此, 的自然顺序与StringBuffer不一致equals。如果StringBuffer对象用作 a 中的键SortedMap或 a中的元素,则应小心谨慎SortedSet



But why?

但为什么?

At the heart of it is the fact that Stringis immutable and StringBuffer/ StringBuilderare mutable.

它的核心String是不可变和StringBuffer/StringBuilder是可变的。

  • If two Stringobjects have the same characters, they will always have the same characters. So it is natural to treat them as equal ... and that is what String::equals(Object)does.

  • If two StringBufferobjects can have the same characters now, and different characters a moment later ... due to a mutating operation performed by another thread. An implementation of equals(Object)for StringBufferthat was sensitive to the (changing) content would be problematic. For example:

    if (buf1.equals(buf2)) {
        // Do something to one of the StringBuffer objects.
    }
    

    has a potential race condition. Another example is use of StringBufferinstances as keys in HashTableor HashMap.

  • 如果两个String对象具有相同的字符,则它们将始终具有相同的字符。所以很自然地将它们视为平等......这就是String::equals(Object)它的作用。

  • 如果两个StringBuffer对象现在可以具有相同的字符,而稍后可以具有不同的字符......由于另一个线程执行的变异操作。对(变化的)内容敏感的equals(Object)for实现StringBuffer将是有问题的。例如:

    if (buf1.equals(buf2)) {
        // Do something to one of the StringBuffer objects.
    }
    

    有潜在的竞争条件。另一个例子是使用StringBuffer实例作为HashTable或 中的键HashMap

At any rate, a deliberate design decision taken a very long time agothat StringBufferand StringBuilderwould not override the Object::equalsand Object::hashCodemethods.

无论如何,很久以前就做出了一个深思熟虑的设计决定,StringBuffer并且StringBuilder不会覆盖Object::equalsObject::hashCode方法。

回答by fastcodejava

Wondering why StringBufferdoes not override the equalsmethod. Probably because the content of the object is obtained by the toString()method and which has the desired method.

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

回答by Ashish Gupta

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

StringBuffer's equals method returns true only when a StringBuffer object is compared with itself. It returns false when compared with any other StringBuffer, even if the two contain the same characters.

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

This is because "==" checks the reference equality and since both sb1 and sb2 are different object references, so the output in this case is "false"

这是因为“==”检查引用相等性,并且由于 sb1 和 sb2 是不同的对象引用,因此在这种情况下的输出为“false”

Still if you want to check if the content is equal in these two StringBuffer Objects, you can use this:

如果你想检查这两个 StringBuffer 对象中的内容是否相等,你可以使用这个:

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

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

This is giving output as "false" because .equals() method has not been overridden in the StringBuffer Class. So it is using the .equals() method from its parent "Object" class. In the object class .equals() has been written to check the reference equality.

这将输出为“false”,因为 .equals() 方法尚未在 StringBuffer 类中被覆盖。所以它使用来自其父“Object”类的 .equals() 方法。在对象类中编写了 .equals() 来检查引用相等性。

Note that sb3.equals(sb4) will return "true" in case of String. Because .equals() method has been overridden in String class to check and match the content of two different Strings.

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

回答by Nikhil Arora

Stringbuffer's equals()is not overridden. It does not compare values, it only compares reference value assignments. That is why you are getting false as they both are referring to different objects.

Stringbufferequals()不会被覆盖。它不比较值,它只比较参考值分配。这就是为什么你会得到错误,因为它们都指的是不同的对象。

回答by Naman

With JDK/11, one can now compare two StringBuffers without an additional toString, this can be done using the newly introduced API -

使用JDK/11,现在可以在StringBuffer没有额外的情况下比较两个s toString,这可以使用新引入的 API 来完成 -

public int compareTo?(StringBuffer another)

Compares two StringBufferinstances lexicographically. This method follows the same rules for lexicographical comparison as defined in the CharSequence.compare(this, another)method. For finer-grained, locale-sensitive String comparison, refer to Collator.

Implementation Note: This method synchronizes on this, the current object, but not StringBuffer anotherwith which this StringBuffer is compared.

Returns: the value 0 if this StringBuffer contains the same character sequence as that of the argument StringBuffer; a negative integer if this StringBuffer is lexicographically less than the StringBuffer argument; or a positive integer if this StringBuffer is lexicographically greater than the StringBuffer argument.

StringBuffer字典顺序比较两个实例。此方法遵循与方法中定义的词典比较相同的规则CharSequence.compare(this, another)。有关更细粒度、对区域设置敏感的字符串比较,请参阅 Collat​​or。

实现说明:此方法同步this,当前对象,而不是与此 StringBuffer 进行比较的另一个StringBuffer 。

返回: 如果此 StringBuffer 包含与参数 StringBuffer 相同的字符序列,则值为 0;如果此 StringBuffer 按字典顺序小于 StringBuffer 参数,则为负整数;如果此 StringBuffer 按字典顺序大于 StringBuffer 参数,则为正整数。

Sample usage :

示例用法:

StringBuffer stringBuffer = new StringBuffer("null");
StringBuffer anotherStringBuffer = new StringBuffer("NULL");
System.out.println(stringBuffer.compareTo(anotherStringBuffer) == 0); // shall print 'false'

回答by Vishal Sheth

-> The String, StringBuffer and StringBuilder extends Object class. -> Object class contain equals() which compare two object memory address/ reference.
-> The equals() method is overridden in String class and it will check the

-> String、StringBuffer 和 StringBuilder 扩展了 Object 类。-> 对象类包含比较两个对象内存地址/引用的 equals()。
-> equals() 方法在 String 类中被覆盖,它将检查

content.tostring()
System.out.println(sbuffer1.toString().equals(sbuffer2.toString()))

-> The equals() method of StringBuffer is not overridden from Object but implements Comparable, so it will compare reference equality, i.e., the same as using ==. in string class and equals() method in object.class. Thus, the natural ordering of StringBuffer is inconsistent with equals.

-> StringBuffer 的 equals() 方法不是从 Object 重写的,而是实现了 Comparable,所以它会比较引用相等,即与使用 == 相同。在字符串类和 object.class 中的 equals() 方法中。因此,StringBuffer 的自然顺序与 equals 不一致。