Яка різниця між 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
повернетьсяfalse
String#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
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()
поверне помилковим, оскільки еквівалентно () перевіряє для 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?