В чем разница между методом String#equals
и String#contentEquals
?
Разница между значениями String # equals и String # contentEquals
Ответ 1
String#equals()
не только сравнивает содержимое String, но также проверяет, является ли другой объект также экземпляром String
. String#contentEquals()
сравнивает только содержимое (последовательность символов) и выполняет не, если другой объект также является экземпляр String
. Это может быть что угодно, если это реализация CharSequence
, которая охватывает a.o. String
, StringBuilder
, StringBuffer
, CharBuffer
и т.д.
Ответ 2
Проще говоря: String.contentEquals()
- более умный брат String.equals()
, потому что он может быть более свободным в реализации, чем String.equals()
.
Есть несколько причин, по которым существует отдельный метод String.contentEquals()
. Самая важная причина, по которой я думаю:
- Метод
equals
должен быть рефлексивным. Это означает, что:x.equals(y) == y.equals(x)
. Это означает, чтоaString.equals(aStringBuffer)
должно быть таким же, какaStringBuffer.equals(aString)
. Для этого разработчикам Java API потребуется сделать специальную реализацию для строк в методеequals()
для StringBuffer, StringBuilder и CharSequence. Это будет беспорядок.
Итак, и именно тогда приходит String.contentEquals
. Это автономный метод, который не должен следовать строгим требованиям и правилам. strong > для Object.equals
. Таким образом, вы можете реализовать чувство "равного содержания" более свободно. Это позволяет делать интеллектуальные сравнения между StringBuffer и String, например.
И чтобы сказать, в чем именно заключается разница:
-
String.contentEquals()
может сравнивать содержимое классовString
, aStringBuilder
, aStringBuffer
, aCharSequence
и всех их производных. Если параметр имеет тип String, тогда выполняетсяString.equals()
. -
String.equals()
сравнивает только объекты String. Все остальные типы объектов считаются не равными. -
String.contentEquals()
может разумно сравниватьStringBuffer
иStringBuilder
. Он не вызывает тяжелый методtoString()
, который копирует весь контент в новый объект String. Вместо этого он сравнивается с базовым массивомchar[]
, который является большим.
Ответ 3
Этот ответ уже был отправлен dbw, но он удалил его, но у него были некоторые очень действительные точки для разницы при сравнении времени выполнения, каких исключений выбрано,
Если вы посмотрите на исходный код String # equals и String # contentEquals ясно, что для String#contentEquals
есть два переопределенных метода, которые принимают StringBuilder
и другие CharSequence
.
Разница между ними,
-
String#contentEquals
выдаст NPE, если аргумент предоставленnull
, ноString#equals
вернетfalse
-
String#equals
сравнивает содержимое только в том случае, если аргументinstance of String
, иначе он будет возвращатьfalse
во всех других случаях, а с другой стороныString#contentEquals
проверяет содержимое всех объектов, реализующих интерфейсCharSequence
. -
Вы также можете настроить код так, чтобы
String#contentEquals
возвращал неверный результат или результат, который вы хотите, переопределяя методequals
аргумента, переданный, как показано ниже, но вы не можете делать эти настройки с помощьюString#equals
.
Ниже код всегда будет выводитьtrue
, еслиs
содержит любойstring
длиной 3 символаString s= new String("abc");// "abc"; System.out.println(s.contentEquals(new CharSequence() { @Override public CharSequence subSequence(int arg0, int arg1) { // TODO Auto-generated method stub return null; } @Override public int length() { // TODO Auto-generated method stub return 0; } @Override public char charAt(int arg0) { // TODO Auto-generated method stub return 0; } @Override public boolean equals(Object obj) { return true; } }));
-
String#contentEquals
будет медленнее, чемString#equals
в том случае, если аргумент представленinstance of String
, а длина обоихstring
одинакова, но содержимое не равно.
Пример, если строкаString s = "madam"
иString argPassed = "madan"
, тогдаs.contentEquals(argPassed)
будет принимать почти двойное время выполнения в этом случае по сравнению сs.equals(argPassed)
-
Если длина содержимого не одинакова для обеих строк, то функция
String#contentEquals
будет иметь лучшую производительность, а затемString#equals
почти во всех возможных случаях.
Еще один момент, чтобы добавить к его ответу
-
String#contentEquals
объектаstring
также будет сравниваться с содержимымStringBuilder
и предоставить соответствующий результат, в то время какString#equals
вернетfalse
Ответ 4
contentEquals(CharSequence cs)
:
- Позволяет проверить равенство заданного строкового значения с любым экземпляром реализации интерфейса
java.lang.CharacterSequence
(например,CharBuffer
,Segment
,String
,StringBuffer
,StringBuilder
)
equals(Object anObject)
:
- Позволяет проверить равенство заданного строкового значения с любым экземпляром типа
java.lang.String
только
RTFC:)
Так как чтение источника - лучший способ его понять, я использую реализации обоих методов (как из jdk 1.7.0_45)
public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
char v1[] = value;
char v2[] = ((AbstractStringBuilder) cs).getValue();
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
// Argument is a String
if (cs.equals(this))
return true;
// Argument is a generic CharSequence
char v1[] = value;
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != cs.charAt(i))
return false;
i++;
}
return true;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Существует еще один метод String # contentEquals():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
Ответ 5
-
String
классequals(Object o)
метод выполняет только сравнениеString
. НоcontentEquals(CharSequence cs)
проверяет классы extendsAbstractStringBuilder
i.e.StringBuffer
,StringBuilder
иString
class также (все они имеют типCharSequence
).String str = "stackoverflow"; StringBuilder builder = new StringBuilder(str); System.out.println(str.equals(builder)); System.out.println(str.contentEquals(builder));
выход:
false
true
Вывод первого stmt равен false
, потому что builder
не имеет тип String
, поэтому equals()
возвращает false
, но contentEquals()
проверяет содержимое всего типа типа StringBuilder
, StringBuffer
, String
, и поскольку содержимое будет таким же, то true
.
-
contentEquals
будет выдаватьNullPointerException
, если аргумент указанnull
, ноequals()
вернет false, потому что equals() проверяет instanceOf (if (anObject instance of String)
), который возвращает false, если аргументnull
.
Ответ 6
equals()
и contentEquals()
- два метода в классе String
для сравнения двух strings
и String
с StringBuffer
.
Параметры contentEquals()
равны StringBuffer
и String(charSequence)
. equals()
используется для сравнения двух strings
и contentEquals()
используется для сравнения содержимого String
и StringBuffer
.
Метод contentEquals
и equals
являются
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Вот код, который описывает оба метода
public class compareString {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
boolean result1 = str1.equals(str2); // works nice and returns true
System.out.println(" str1.equals(str2) - "+ result1);
boolean result2 = str1.equals(sb1); // works nice and returns false
System.out.println(" str1.equals(sb1) - "+ result2);
boolean result3 = str1.contentEquals(sb1); // works nice and returns true
System.out.println(" str1.contentEquals(sb1) - "+ result3);
boolean result4 = str1.contentEquals(sb2); // works nice and returns false
System.out.println(" str1.contentEquals(sb2) - "+ result4);
boolean result5 = str1.contentEquals(str2); // works nice and returns true
System.out.println(" str1.contentEquals(str2) - "+ result5);
}
}
Вывод:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
Ответ 7
Проверка метода contentEquals()
- это то же самое содержимое между String
, StringBuffer
и т.д., которое представляет собой последовательность char.
Ответ 8
String # equals принимает объект как аргумент и проверяет его как экземпляр объекта String или нет. Если объектом аргумента является String Object, он сравнивает символ содержимого по символу. Он возвращает true, если содержимое обоих строковых объектов одинаково.
String # contentEquals использует интерфейс CharSequence в качестве аргумента. CharSequence может быть реализован двумя способами: с помощью i) класса String или (ii) AbstractStringBuilder (родительский класс StringBuffer, StringBuilder)
В contentEquals() длина сравнивается перед проверкой экземпляра объекта. Если длина такая же, то проверка объекта аргумента является экземпляром AbstractStringBuilder или нет. Если это так (т.е. StringBuffer или StringBuilder), то содержимое проверяется символом по символу. В случае, если аргумент является экземпляром объекта String, тогда String # равнозывается из String # contentEquals.
Итак,
String # equals сравнивает символ содержимого по символу, если аргумент аргумента также является объектом String. И String # contentEquals сравнивает содержимое в объекте аргумента, реализующего интерфейс CharSequence.
String # contentEquals медленнее, если мы сравниваем содержимое строки с одинаковой длиной, как String # contentEquals внутренне вызывает String # equals для объекта String.
Если мы попытаемся сравнить объекты с длиной содержимого разницы (скажем, "abc" с "abcd" ), то String # contentEquals быстрее, чем String # equals. Поскольку длина сравнивается перед проверкой экземпляра объекта.
Ответ 9
Кстати, историческая причина разницы в том, что у String изначально не было суперкласса, поэтому String.equals() принимает в качестве аргумента строку. Когда CharSequence был представлен как суперкласс String, ему нужен был собственный тест равенства, который работал во всех реализациях CharSequence и не сталкивался бы с equals(), уже используемым String... поэтому мы получили CharSequence.contentEquals(), который наследуется String.
Если CharSequence присутствует в Java 1.0, мы бы предположили, что только CharSequence.equals() и String просто реализуют это.
А, радости эволюционирующих языков...
Ответ 10
Большая разница в том, что equals() будет работать только с другой строкой, а contentEquals() будет работать с любой CharacterSequence (например, StringBuilder).
public class Test{
public static void main(String[] args)
{
String str1 = "Hello";
String str2 = new String("Hello");
StringBuilder str3 = new StringBuilder(str1);
System.out.println("str1.equals(str2): " + (str1.equals(str2)));
System.out.println("str1.contentEquals(str2): " + (str1.contentEquals(str2)));
System.out.println("str1.equals(str3): " + (str1.equals(str3)));
System.out.println("str1.contentEquals(str3): " + (str1.contentEquals(str3)));
}}
даст результат как
str1.equals(str2): true
str1.contentEquals(str2): true
str1.equals(str3): false
str1.contentEquals(str3): true