В чем разница между String#equals
методом и String#contentEquals
методом?
В чем разница между String#equals
методом и String#contentEquals
методом?
Ответы:
Он String#equals()
не только сравнивает содержимое строки, но также проверяет, является ли другой объект также экземпляром String
. String#contentEquals()
Только сравнивает содержимое (последовательность символов) и не не проверить , если другой объект также является экземпляром String
. Это может быть что угодно , до тех пор , как это реализация CharSequence
которых охватывает ао String
, StringBuilder
, StringBuffer
, CharBuffer
и т.д.
==
оператор разрешает сравнивать только ссылки, а не содержимое двух объектов.
==
упомянутый только JavaScript; это никогда не упоминается в отношении Java.
==
в JavaScript гораздо слабее, чем contentEquals
, например, не будет касаться цифр), но вы правильно equals
проверяете точное совпадение типов сStrings
(другие классы могут быть слабее с типами в их equals
методах) ,
Проще говоря: String.contentEquals()
это умный брат String.equals()
, потому что он может быть более свободным в реализации, чем String.equals()
.
Есть несколько причин, почему существует отдельный String.contentEquals()
метод. Самая важная причина, я думаю, это:
equals
Метод должен быть рефлексивными. Это означает , что: x.equals(y) == y.equals(x)
. Это подразумевает, что aString.equals(aStringBuffer)
должно быть так же, как aStringBuffer.equals(aString)
. Это потребует от разработчиков Java API создания специальной реализации для Strings в equals()
методах StringBuffer, StringBuilder и CharSequence. Это было бы беспорядок.Это где String.contentEquals
приходит. Это метод автономного , который никак не должен следовать строгим требованиям и правилам для Object.equals
. Таким образом, вы можете более свободно реализовать смысл «равного содержания» . Это позволяет вам делать интеллектуальные сравнения, например, между StringBuffer и String.
И сказать, в чем именно разница:
String.contentEquals()
может сравнить содержимое a String
, a StringBuilder
, a StringBuffer
, a CharSequence
и всех производных классов из них. Если параметр имеет тип String, то String.equals()
выполняется.
String.equals()
сравнивает только строковые объекты. Все остальные типы объектов считаются не равными.
String.contentEquals()
Можно сравнить StringBuffer
и StringBuilder
по-умному. Он не вызывает тяжелый toString()
метод, который копирует весь контент в новый объект String. Вместо этого он сравнивается с базовым char[]
массивом, и это здорово.
Этот ответ уже был опубликован 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
String
equals(Object o)
метод класса делает только String
сравнение. Но contentEquals(CharSequence cs)
проверка на классы распространяется AbstractStringBuilder
ИЭ StringBuffer
, StringBuilder
и String
класс также (все они имеют тип CharSequence
).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
вывод:
false
true
Выход первого зЬтЬ это false
потому , что builder
не относится к типу String
так equals()
возвращается , false
но на contentEquals()
проверку на содержание всех типов , как StringBuilder
, StringBuffer
, String
и , как содержание такой же поэтому true
.
contentEquals
сгенерирует, NullPointerException
если задан аргумент, null
но equals()
вернет false, потому что equals () проверяет instanceOf ( if (anObject instance of String)
), который возвращает false, если аргумент равен null
.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);
}
}
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
String # equals принимает Object в качестве аргумента и проверяет, является ли он экземпляром объекта String или нет. Если аргументом является объект String, он сравнивает содержимое символ за символом. Возвращает true, если содержимое обоих строковых объектов одинаково.
String # contentEquals принимает интерфейс CharSequence в качестве аргумента. CharSequence может быть реализован двумя способами: с помощью i) класса String или (ii) AbstractStringBuilder (родительский класс StringBuffer, StringBuilder)
В contentEquals () длина сравнивается перед проверкой любого экземпляра объекта. Если длина одинакова, то проверяется, является ли объект аргумента экземпляром AbstractStringBuilder или нет. Если это так (т.е. StringBuffer или StringBuilder), то содержимое проверяется посимвольно. Если аргумент является экземпляром объекта String, тогда String # equals вызывается из String # contentEquals.
Короче говоря,
String # equals сравнивает содержимое символ за символом в случае, если аргумент также является объектом String. And String # contentEquals сравнивает содержимое в случае, если объект аргумента реализует интерфейс CharSequence.
String # contentEquals работает медленнее, если мы сравниваем два строковых содержимого одинаковой длины, так как String # contentEquals внутренне вызывает String # equals для объекта String.
Если мы пытаемся сравнить объекты с разной длиной содержимого (скажем, «abc» с «abcd»), то String # contentEquals быстрее, чем String # равно. Потому что длина сравнивается перед проверкой экземпляра объекта.
В contentEquals()
проверяет метод является содержание же между а String
,StringBuffer
и т.д. , которые какое - то последовательность полукокса.
Кстати, историческая причина разницы в том, что String изначально не имел суперкласса, поэтому String.equals () принимает String в качестве аргумента. Когда CharSequence был представлен в качестве суперкласса String, он нуждался в собственном тесте на равенство, который работал бы во всех реализациях CharSequence и который не вступал бы в конфликт с equals (), уже используемым String ... поэтому мы получили CharSequence.contentEquals ( ), который наследуется String.
Если бы CharSequence присутствовал в Java 1.0, мы, вероятно, имели бы только CharSequence.equals (), и String просто реализовал бы это.
Ах, радости развивающихся языков ...
==
(contentEquals) и===
(равно) в JavaScript?