Сравнение содержимого StringBuffer с равными - PullRequest
23 голосов
/ 06 января 2010
StringBuffer sb1 = new StringBuffer("Java");
StringBuffer sb2 = new StringBuffer("Java");
System.out.println(sb1 == sb2);
System.out.println(sb1.equals(sb2));

Здесь оба возвращают ложь. Как это возможно?

Ответы [ 9 ]

33 голосов
/ 06 января 2010

Метод equals для StringBuffer не переопределяется из Object, так что это просто ссылочное равенство, то есть то же самое, что и ==. Я подозреваю, что причина этого в том, что StringBuffer является изменяемым, а переопределение equals в основном полезно для классов, подобных значениям, которые вы, возможно, захотите использовать в качестве ключей (хотя списки также имеют переопределенные equals и StringBuffer вроде списка, так что это немного противоречиво).

23 голосов
/ 06 января 2010

Вы сравниваете ссылки на объекты StringBuffer, а не фактические строки в StringBuffer.

System.out.println(sb1.toString().equals(sb2.toString())) вернул бы true, и я предполагаю, что это то, что вы ожидали или хотели достичь.

7 голосов
/ 03 февраля 2010

Простой ответ заключается в том, что StringBuffer (и StringBuilder) не переопределяют базовую семантику Object.equals (). Поэтому equals в StringBuffer будет просто сравнивать ссылки на объекты.

Фактически, String, StringBuffer, StringBuilder и CharBuffer все реализуют интерфейс CharSequence , и Javadoc для этого интерфейса говорит это:

Этот интерфейс не уточняет общие контракты методов equals и hashCode. Поэтому результат сравнения двух объектов, реализующих CharSequence, вообще не определен. Каждый объект может быть реализован отдельным классом, и нет никакой гарантии, что каждый класс сможет проверить свои экземпляры на равенство с экземплярами другого. Поэтому нецелесообразно использовать произвольные экземпляры CharSequence в качестве элементов в наборе или в качестве ключей на карте.

6 голосов
/ 11 августа 2013
 1.  System.out.println(sb1 == sb2);  

Метод equals StringBuffer возвращает true, только когда объект StringBuffer сравнивается с самим собой. Он возвращает false при сравнении с любым другим StringBuffer, даже если они содержат одинаковые символы.

Это потому, что "==" проверяет равенство ссылок и поскольку sb1 и sb2 являются разными ссылками на объекты, поэтому вывод в этом случае "false"

Тем не менее, если вы хотите проверить, равно ли содержимое в этих двух объектах StringBuffer, вы можете использовать это:

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

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

Это дает вывод как "false", потому что метод .equals () не был переопределен в классе StringBuffer. Так что он использует метод .equals () из родительского класса «Object». В объектном классе .equals () был написан для проверки равенства ссылок.

Обратите внимание, что sb3.equals (sb4) вернет "true" в случае String. Поскольку метод .equals () был переопределен в классе String для проверки и сопоставления содержимого двух разных строк.

3 голосов
/ 06 января 2010

оба сравнивают две ссылки на объекты (sb1 - одно, а sb2 - второе), поэтому оба они различны.

Если вы пытаетесь сравнить контент - используйте метод compareTo (...) in String class - то есть - сначала получите String content StringBuffer с использованием метода toString () ( .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())); 
3 голосов
/ 06 января 2010

StringBuffer, похоже, не имеет собственного метода equals, поэтому мое первое предположение заключается в том, что StringBuffer наследует метод equals Object, который сравнивается с использованием sb1 == sb2. Поэтому оба метода дают один и тот же результат.

1 голос
/ 10 августа 2018

С JDK / 11 теперь можно сравнивать два StringBuffer без дополнительного toString, это можно сделать с помощью недавно представленного API -

public int compareTo​(StringBuffer another)

Сравнивает два StringBuffer экземпляра лексикографически. Этот метод следует тем же правилам лексикографического сравнения, которые определены в метод CharSequence.compare(this, another). Для более детального сравнения строк с учетом локали см. Collator.

Замечание по реализации : этот метод синхронизирует с этим , текущим объект, но не StringBuffer другой , с которым этот StringBuffer по сравнению.

Возвращает : значение 0, если этот StringBuffer содержит тот же символ последовательность как аргумент StringBuffer; отрицательное целое число, если этот StringBuffer лексикографически меньше, чем StringBuffer аргумент; или положительное целое число, если этот StringBuffer лексикографически больше, чем аргумент StringBuffer.

Пример использования:

StringBuffer stringBuffer = new StringBuffer("null");
StringBuffer anotherStringBuffer = new StringBuffer("NULL");
System.out.println(stringBuffer.compareTo(anotherStringBuffer) == 0); // shall print 'false'
1 голос
/ 03 февраля 2010

Хотите знать, почему StringBuffer не переопределяет метод equals. Вероятно потому, что содержимое объекта получается методом toString() и имеет нужный метод.

0 голосов
/ 13 ноября 2016

Stringbuffer equals() не переопределяется.Он не сравнивает значения, он только сравнивает присвоения эталонных значений.Вот почему вы получаете ложь, поскольку они оба ссылаются на разные объекты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...