Яка різниця між String#equalsметодом і String#contentEqualsметодом?
Яка різниця між String#equalsметодом і String#contentEqualsметодом?
Відповіді:
Він String#equals()не тільки порівнює вміст String, але і перевіряє, чи є інший об'єкт також екземпляром a 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. Усі інші типи об'єктів вважаються не рівними.
String.contentEquals()можна порівняти StringBufferі StringBuilderінтелектуально. Він не викликає важкого toString()методу, який копіює весь вміст у новий об'єкт String. Натомість він порівнює з базовим char[]масивом, що чудово.
Цю відповідь вже розмістив dbw, але він видалив її, але у нього були дуже вагомі бали за різницю, порівнюючи час виконання, які винятки викидаються,
Якщо ви подивитеся на вихідний код, рядок # дорівнює та String # contentEquals, то зрозуміло, що існує два перекритих методу для String#contentEqualsодного, який приймає StringBuilderта іншого CharSequence.
Різниця між ними,
String#contentEqualsкине NPE, якщо аргумент наданий, nullале String#equalsповернетьсяfalseString#equalsпорівнює вміст лише тоді, коли аргумент, що подається, instance of Stringінакше він повернеться falseу всіх інших випадках, але з іншого боку String#contentEqualsперевіряє вміст усіх об'єктів, що реалізують інтерфейс CharSequence.Ви також можете налаштувати код так, щоб String#contentEqualsповернути потрібний результат або результат, який ви бажаєте, пересунувши equalsметод аргументу, що передається, як показано нижче, але ви не можете робити ці зміни String#equals.
Нижче наведено код завждиtrue тих пір, поки sмістить будь- stringякий, який має три символи
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 Stringequals(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()поверне помилковим, оскільки еквівалентно () перевіряє для instanceOf ( if (anObject instance of String)), який повертає помилкове, якщо аргумент є 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;
}
Існує ще один метод рядка # 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 Object, то він порівнює вміст символів за символами. Він повертає істину, якщо вміст обох рядкових об'єктів однаковий.
Рядок # contentEquals contentEquals бере аргумент інтерфейсу CharSequence. CharSequence можна реалізувати двома способами, використовуючи i) клас String або (ii) AbstractStringBuilder (батьківський клас StringBuffer, StringBuilder)
У contentEquals () довжина порівнюється перед будь-якою перевіркою екземпляра об'єкта. Якщо довжина однакова, він перевіряє об'єкт аргументу - це примірник AbstractStringBuilder чи ні. Якщо це так (тобто StringBuffer або StringBuilder), то вміст перевіряється символом за символом. У випадку, якщо аргумент є екземпляром об'єкта String, тоді String # дорівнює виклику з String # contentEquals.
Отже, коротше,
Рядок # дорівнює порівнянні символу вмісту за символом, якщо аргументом також є об'єкт String. І String # contentEquals порівнює вміст у випадку, якщо об’єкт аргументу реалізує інтерфейс CharSequence.
String # contentEquals проходить повільніше, якщо ми порівнюємо два рядкових контенту однакової довжини, як String # contentEquals, внутрішньо викликає String # рівний для String об'єкта.
У випадку, якщо ми спробуємо порівняти об'єкти з різницею довжини вмісту (скажімо, "abc" з "abcd"), то String # contentEquals швидше, ніж String # дорівнює. Тому що довжина порівнюється перед будь-якою перевіркою екземпляра об'єкта.
У contentEquals()перевіряє метод є зміст же між а String, StringBufferі т.д. , які яке - то послідовність напівкоксу.
До речі, історична причина різниці полягає в тому, що String спочатку не мав надкласу, тому String.equals () бере аргумент String як аргумент. Коли CharSequence було представлено як суперклас String, йому знадобився власний тест рівності, який працював у всіх реалізаціях CharSequence, і це не зіткнеться з рівнем (), який вже використовується String ... тому ми отримали CharSequence.contentEquals ( ), що успадковується String.
Якщо CharSequence був присутній у Java 1.0, ми б заборонили мати лише CharSequence.equals (), а String це просто реалізував би.
Ах, радощі мов, що розвиваються ...
==(contentEquals) та===(equals) в JavaScript?