Как сравнить равенство 2 объекта StringBuffer / StringBuilder? [Дубликат]

Типы ссылок по умолчанию равны null, чтобы указать, что они не ссылаются на какой-либо объект. Следовательно, если вы попытаетесь получить доступ к объекту, на который ссылаетесь, а его нет, вы получите исключение NullReferenceException.

Для Ex:

SqlConnection connection = null;
connection.Open();

Когда вы запускаете это кода, вы получите:

System.NullReferenceException: Object reference not set to an instance of an object.

Вы можете избежать этой ошибки, например, следующим образом:

if (connection != null){
    connection.Open();
}

Примечание. Чтобы избежать этой ошибки, вы всегда должны инициализировать свои объекты прежде чем пытаться что-либо сделать с ними.

22
задан teabot 3 February 2010 в 14:16
поделиться

9 ответов

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

30
ответ дан JaakkoK 3 September 2018 в 18:26
поделиться
  • 1
    Поскольку я просто попал в ту же яму, я бы хотел заметить, что это просто глупое дизайнерское решение : вместо sb1.equals(sb2) мне придется писать sb1.toString().equals(sb2.toString()) (потому что это то, что на самом деле имеет значение). Возможно, это также причина. Помимо текущего содержимого, есть внутренние атрибуты (например, емкость буфера), которые могут или не могут повлиять на представление о равенстве. Наконец: hashCode() имеет ту же проблему. – U. Windl 28 May 2018 в 09:03
 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));

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

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

6
ответ дан Ashish Gupta 3 September 2018 в 18:26
поделиться

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

Если вы пытаетесь сравнить контент - используйте метод compareTo (...) в String class - это - сначала получить String содержимое 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
ответ дан David Rodríguez - dribeas 3 September 2018 в 18:26
поделиться
  • 1
    Насколько я знаю, StringBuilder не является потокобезопасным – Yaneeve 6 January 2010 в 12:18
  • 2
    StringBuilder не является потокобезопасным. Из SDK-документов на StringBuilder: «совместим с StringBuffer, но с нет гарантии синхронизации », из параграфа введения здесь: java.sun.com/j2se/1.5.0/ документы / API / Java / языки / StringBuilder.html – David Rodríguez - dribeas 6 January 2010 в 12:26
  • 3
    конечно, мое плохое. прочитайте документ StringBuffer слишком быстро, IT дополняется StringBuilder, поэтому он предназначен для использования одним потоком. простите за это. – mkolodziejski 6 January 2010 в 12:32
  • 4
    Дело в том, что оно быстрее, потому что оно устраняет требование безопасности потока от StringBuffer – David Rodríguez - dribeas 6 January 2010 в 12:45
  • 5
    Поскольку JDK 1.6, lock elision делает разницу между StringBuffer и StringBuilder незначительной. Тем не менее, я не знаю деталей, возможно, блокировка elision не способна усваивать более сложные варианты использования, поэтому всегда лучше использовать StringBuilder, если вам не нужна безопасность потоков. – Oliv 27 July 2016 в 06:47

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

1
ответ дан fastcodejava 3 September 2018 в 18:26
поделиться

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

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

21
ответ дан Mark 3 September 2018 в 18:26
поделиться

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

0
ответ дан Nikhil Arora 3 September 2018 в 18:26
поделиться

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

public int compareTo​(StringBuffer another)

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

Замечание по реализации : этот метод синхронизирует на этот текущий объект, но а не 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
ответ дан nullpointer 3 September 2018 в 18:26
поделиться
  • 1
    Публикация этого ответа, так как большинство вопросов, связанных со сравнением StringBuffer, заканчиваются здесь. – nullpointer 10 August 2018 в 13:44

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

3
ответ дан Scharrels 3 September 2018 в 18:26
поделиться

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

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

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

5
ответ дан Stephen C 3 September 2018 в 18:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: