Як я порівнюю рядки в Java?


724

Я використовував ==оператор у своїй програмі, щоб порівняти всі мої рядки досі. Однак я зіткнувся з помилкою, змінив одну з них .equals()замість цього, і він виправив помилку.

Чи ==погано? Коли його слід застосовувати і чи не слід його використовувати? Яка різниця?


12
Також добре знати, що якщо ви переосмислюєте метод .equals (), переконайтеся, що ви переосмислили метод .hashcode (), інакше у вас виявиться порушення порушення еквівалентності b / w рівне і хеш-код. Для отримання додаткової інформації зверніться до java doc.
Нагесваран

Залишаючи посилання на моє пояснення того, чому ==працює так, як це робиться на об’єктах: stackoverflow.com/a/19966154/2284641
Йоганнес Х.

==буде працювати деякий час, оскільки java має String пул, де він намагається повторно використовувати посилання на пам'ять часто використовуваних рядків. Але ==порівнюємо, що об'єкти рівні, а не значення ... так .equals()це правильне використання, яке ви хочете використовувати.
Джеймс Оравець

Ніколи не використовуйте == для перевірки того, чи струни однакові, якщо вам не подобається відслідковувати тонкі помилки та вивчати тонкощі процесу інтернації Java String. "12"=="1"+2неправдиво (ймовірно)
Одісея з польоту

Відповіді:


5560

== тести на еталонну рівність (чи є вони однаковим об'єктом).

.equals() тести на величину рівності (чи є вони логічно «рівними»).

Predcts.equals () перевіряє, nullперш ніж дзвонити, .equals()щоб вам не доведеться (доступно з JDK7, також доступний у Guava ).

Отже, якщо ви хочете перевірити, чи мають два рядки однакове значення, ви, ймовірно, захочете використовувати Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Ви майже завжди хочете використовувати Objects.equals(). У рідкісній ситуації, коли ви знаєте, що маєте справу з інтернованими струнами, ви можете використовувати ==.

Від JLS 3.10.5. Строкові літерали :

Більше того, рядковий літерал завжди посилається на один і той же екземпляр класу String. Це тому, що рядкові літерали - або, загалом, рядки, що є значеннями постійних виразів ( §15.28 ) - "інтерновані", щоб поділитися унікальними екземплярами, використовуючи метод String.intern.

Подібні приклади можна також знайти в JLS 3.10.5-1 .

Інші методи для розгляду

String.equalsIgnoreCase () значення рівності, яке ігнорує регістр.

String.contentEquals () порівнює вміст вмісту Stringз вмістом будь-якого CharSequence(доступний з Java 1.5). Врятує вас від необхідності перетворювати StringBuffer тощо у рядок, перш ніж проводити порівняння рівності, але залишає вам перевірку нуля.


3
Якщо == перевіряє еталонну рівність, чому n == 5 має сенс? 5 не є змінною
Hrit Roy

2
@HritRoy Тому що ==перевіряє значення змінної. Коли у вас є об'єкт, змінна, на яку посилається об'єкт, має посилання на об'єкт як значення . Таким чином, ви порівнюєте посилання при порівнянні двох змінних ==. Якщо порівнювати примітивний тип даних, такий як int, це все одно той самий випадок. Змінна типу intмає ціле число як значення. Таким чином, ви порівнюєте значення двох ints за допомогою ==. Якщо intзначення є змінною або магічне число не має значення. Крім того: посилання не що інше число , яке відноситься до пам'яті.
акузміних

718

==тестує посилання на об'єкт, .equals()тестує рядкові значення.

Іноді це виглядає так, ніби ==порівнює значення, тому що Java виконує деякі закулісні речі, щоб переконатися, що однакові рядкові рядки насправді є одним і тим же об'єктом.

Наприклад:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Але остерігайтеся нулів!

==обробляє nullрядки штрафом, але виклик .equals()з нульового рядка спричинить виняток:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Тож якщо ви знаєте, що це fooString1може бути недійсно, повідомте це читачеві, пишучи

System.out.print(fooString1 != null && fooString1.equals("bar"));

Нижче наведено коротше, але менш очевидно, що він перевіряє нуль:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

86
Іноді це виглядає , як якщо б «==» порівнює значення, - == робити завжди порівнюють значення! (Просто певні значення є посиланнями!)
aioobe

6
На жаль, не існує статичного методу для isNullOrEmpty () і немає спеціальних перевантажень операторів, що робить цю частину Java незграбнішою, ніж у C # або Python. А оскільки у Java немає методів розширення, ви не можете написати власну утиліту для розширення java.lang.String. Правильно? Будь-які думки про підкласинг String, додавши цей метод статичної корисності, а потім завжди використовуючи MyString? Статичний метод з двома параметрами для порівняння з нульовими порівняннями було б непогано мати і в цьому підкласі.
Джон Кумбс

7
Groovy робить це трохи легше з безпечної навігації оператора ( groovy.codehaus.org / ... ) ?.. Це перетворило б nullString1?.equals(nullString2);на абсолютно нульове твердження. Однак це не допомагає, якщо у вас є validString?.equals(nullString);- це все-таки є винятком.
Чарльз Вуд

5
Короткі методи для порівняння NULLABLE рядків в Java: stackoverflow.com/questions/11271554 / ...
Вадиму

5
@JonCoombs Java підтримує підкласифікацію та створення власного методу. Однак деякі класи позначені остаточними з певних причин, String - це один із них, тому ми не можемо продовжувати. Ми можемо створити інший клас і зробити там корисний клас, який бере два аргументи як аргументи і реалізує там свою логіку. Також для нульової перевірки деяких інших бібліотек, таких як spring і apache він хороші колекції методів, можна використовувати це.
Пантера

442

== порівнює посилання на об'єкти.

.equals() порівнює значення рядків.

Іноді ==створює ілюзії порівняння рядкових значень, як у наступних випадках:

String a="Test";
String b="Test";
if(a==b) ===> true

Це тому, що коли ви створюєте будь-який лінійний рядок, JVM спочатку здійснює пошук цього літералу в пулі String, і якщо він знайде збіг, те саме посилання буде надане для нового String. Через це ми отримуємо:

(a == b) ===> вірно

                       String Pool
     b -----------------> "test" <-----------------a

Однак ==не вдається в наступному випадку:

String a="test";
String b=new String("test");
if (a==b) ===> false

У цьому випадку для new String("test")заяви новий String буде створений на купі, і ця посилання буде надана b, тому bбуде надано посилання на купу, а не в String пулі.

Тепер aвказує на String у басейні String, а bвказує на String на купі. Через це ми отримуємо:

if (a == b) ===> false.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Хоча .equals()завжди порівнює значення String, щоб воно було істинним в обох випадках:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Тож використання .equals()завжди краще.


3
.equals () порівнює два екземпляри, однак для їх порівняння реалізовано рівне. Це може або не може порівнювати вихід ToString.
Яків

3
@Jacob .equals()Метод класу Object порівнює випадки (посилання / Адреса), коли як .equals()метод String класу
переосмислюється

1
Добре підкреслюючи рядок рядків порівняно з різними кучами Java, оскільки вони, безумовно, не однакові. У ряді рядків Java намагається «кешувати» Stringоб’єкти, щоб зберегти слід пам’яті, як Stringвідомо, що він незмінний (сподіваюся, тут я це правильно кажу). Також перевірте stackoverflow.com/questions/3052442/…
Roland

1
Це відповідь, яку я шукав.
Weezy

Яка чудова відповідь!
alwbtc

223

У ==перевіряє оператор , щоб побачити , якщо два рядки в точності той же об'єкт.

.equals()Метод буде перевірити , якщо два рядки мають однакове значення.


5
Як правило, я настійно рекомендую бібліотеку apache commons: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)
Marcin Erbel

179

Рядки на Java незмінні. Це означає, що коли ви намагаєтесь змінити / змінити рядок, ви отримаєте новий екземпляр. Ви не можете змінити початковий рядок. Це зроблено для того, щоб ці екземпляри рядків можна було кешувати. Типова програма містить безліч посилань на рядки, і кешування цих екземплярів може зменшити слід пам'яті та підвищити продуктивність програми.

Використовуючи оператор == для порівняння рядків, ви не порівнюєте вміст рядка, але насправді порівнюєте адресу пам'яті. Якщо вони обидва рівні, то в іншому випадку повернеться істинне та хибне. Тоді як рівне в рядку порівнює вміст рядка.

Отже, питання полягає в тому, якщо всі рядки є кешованими в системі, як приходить ==повернення false, тоді як дорівнює return true? Ну, це можливо. Якщо ви створили нову рядок, як би String str = new String("Testing")ви в кінцевому підсумку створили нову рядок у кеші, навіть якщо кеш вже містить рядок із тим самим вмістом. Коротше кажучи "MyString" == new String("MyString"), завжди повернеться помилковим.

Java також розповідає про функцію intern (), яку можна використовувати в рядку, щоб зробити її частиною кешу, тому "MyString" == new String("MyString").intern()повернеться true.

Примітка: Оператор == набагато швидше, ніж дорівнює тому, що ви порівнюєте дві адреси пам'яті, але вам потрібно бути впевненим, що код не створює нових екземплярів String у коді. Інакше ви зіткнетеся з помилками.


147
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

Переконайтеся, що ви зрозуміли, чому. Це тому, що ==порівняння порівнює лише посилання; equals()метод робить символ за символом порівняння вмісту.

Коли ви зателефонуєте за новим aі b, кожен отримує нове посилання, яке вказує на "foo"таблицю рядків. Посилання різні, але зміст однаковий.


128

Так, це погано ...

==означає, що ваші дві рядкові посилання є абсолютно одним і тим же об'єктом. Можливо, ви чули, що це так, тому що Java зберігає свого роду буквальну таблицю (що це робить), але це не завжди так. Деякі рядки завантажуються різними способами, побудованими з інших рядків тощо, тому ніколи не слід вважати, що дві однакові рядки зберігаються в одному місці.

Дорівнює справжньому порівнянню для вас.


124

Так, ==це погано для порівняння рядків (будь-які об'єкти справді, якщо ви не знаєте, що вони канонічні). ==просто порівнює посилання на об'єкти. .equals()тести на рівність. Для струнних часто вони будуть однаковими, але, як ви виявили, це не завжди гарантується.


118

У Java є пул String, під яким Java управляє розподілом пам'яті для об'єктів String. Див. Стрункові пули на Java

Коли ви перевіряєте (порівнюєте) два об'єкти за допомогою ==оператора, він порівнює рівність адреси на пул рядків. Якщо два об'єкти String мають однакові посилання на адресу, він повертається true, інакше false. Але якщо ви хочете порівняти вміст двох об'єктів String, тоді ви повинні перекрити equalsметод.

equals насправді є методом класу Object, але він переосмислюється в клас String і дається нове визначення, яке порівнює вміст об'єкта.

Example:
    stringObjectOne.equals(stringObjectTwo);

Але пам'ятайте, що вона поважає випадок String. Якщо ви хочете порівняти з регістром, тоді вам слід скористатися методом equalsIgnoreCase класу String.

Подивимось:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE

7
Я бачу, що це пізня відповідь на велике запитання. Чи можу я запитати, що це передбачає, що вже не згадується в існуючих відповідях?
Містичний

6
@Mysticial він додав, equalsIgnoreCaseщо може бути корисним для свіжіших .
AmitG

103

Я згоден з відповіддю із зачератів.

Але те, що ти можеш зробити, - це закликати intern()до своїх нелітеральних рядків.

З прикладу zacherates:

// ... but they are not the same object
new String("test") == "test" ==> false 

Якщо ви інтернуєте нелітеральну рівність рядка, це true:

new String("test").intern() == "test" ==> true 

8
Це взагалі не дуже гарна ідея. Інтернування є відносно дорогим і може (як не парадоксально) >> збільшити << слід пам'яті JVM та збільшити витрати на GC. У більшості випадків вони перевищують ефективність від використання ==для порівняння рядків.
Stephen C

101

==порівнює посилання на об'єкти в Java , і це не є винятком для Stringоб'єктів.

Для порівняння фактичного вмісту об’єктів (у тому числі String) треба використовувати equalsметод .

Якщо виявляється порівняння двох Stringоб'єктів, що використовуються , це пов'язано з тим, що об'єкти були інтерновані, і віртуальна машина Java має кілька посилань на один і той же екземпляр . Не слід очікувати, що порівнюючи один об'єкт, що містить той самий вміст, як інший об'єкт, використовуючи для оцінки як .==trueStringStringStringString==true


99

.equals()порівнює дані в класі (припускаючи, що функція реалізована). ==порівнює місця вказівника (розташування об'єкта в пам'яті).

==повертає істину, якщо обидва об'єкти (НЕ говорять про ПРИМІТИВИ) вказують на екземпляр об'єкта SAME. .equals()повертає true, якщо два об'єкти містять однакові дані equals()Versus ==на Java

Це може вам допомогти.


95

==здійснює перевірку рівності еталонних даних , чи 2 об'єкти (рядки в цьому випадку) посилаються на один і той же об'єкт у пам'яті.

equals()Метод перевірятиме чи вміст або ж стану з 2 -х об'єктів є однаковими.

Очевидно, що ==це швидше, але в багатьох випадках (можливо) дасть помилкові результати, якщо ви просто хочете сказати, чи утримується 2 Stringс однаковий текст.

Однозначно рекомендується використовувати equals()метод.

Не турбуйтеся про виступ. Деякі речі, які слід заохотити до використання String.equals():

  1. Здійснення String.equals()перших перевірок рівності еталону (з використанням ==), і якщо 2 рядки однакові за посиланням, подальший розрахунок не проводиться!
  2. Якщо посилання на 2 рядки не однакові, String.equals()наступна перевірка довжини рядків. Це також швидка операція, оскільки Stringклас зберігає довжину рядка, не потрібно рахувати символи чи кодові очки. Якщо довжини відрізняються, подальша перевірка не проводиться, ми знаємо, що вони не можуть бути рівними.
  3. Тільки якщо ми досягли цього далеко, буде фактично порівнюватися вміст 2-х рядків, і це буде короткочасне порівняння: не всі символи будуть порівнюватися, якщо ми знайдемо невідповідний символ (на тій же позиції у двох рядках ), подальші символи не перевірятимуться.

Коли все буде сказано і зроблено, навіть якщо ми маємо гарантію, що рядки є стажистами, використання equals()методу все ще не є таким накладним, що можна подумати, безумовно, рекомендованим способом. Якщо ви хочете ефективної перевірки довідок, тоді використовуйте переліки, де це гарантується мовною специфікацією та реалізацією, що те саме значення перерахунку буде тим самим об'єктом (за посиланням).


2
Obviously == is faster- фактично здійснення .equals(String)перших перевірок ==перед чим-небудь іншим, тому я б сказав, що швидкість приблизно однакова.
Razzle Shazl

2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl

82

Якщо ви схожі на мене, коли я вперше почав використовувати Java, я хотів скористатися оператором "==", щоб перевірити, чи рівні два екземпляри String, але в кращому чи гіршому випадку, це не правильний спосіб зробити це на Java.

У цьому підручнику я продемонструю кілька різних способів правильно порівняти рядки Java, починаючи з підходу, яким я користуюся більшу частину часу. Наприкінці цього посібника зі порівняння рядків Java я також обговорюю, чому оператор "==" не працює при порівнянні рядків Java.

Варіант 1: Порівняння рядків Java з методом рівних Більшу частину часу (можливо, 95% часу) я порівнюю рядки з методом рівних класу Java String, як це:

if (string1.equals(string2))

Цей метод String equals розглядає два рядки Java, і якщо вони містять абсолютно однаковий рядок символів, вони вважаються рівними.

Подивившись на швидкий приклад порівняння рядків із методом рівних, якщо запустити наступний тест, два рядки не вважатимуться рівними, оскільки символи не однакові (справа символів відрізняється):

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

Але, коли два рядки містять абсолютно однаковий рядок символів, метод рівняння поверне справжнє значення, як у цьому прикладі:

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Варіант 2: Порівняння рядків із методом equalsIgnoreCase

У деяких тестах порівняння рядків ви хочете ігнорувати, чи є рядки великими або малими літерами. Коли ви хочете перевірити свої рядки на рівність таким нечутливим до випадку способом, використовуйте метод equalsIgnoreCase класу String, наприклад:

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

Варіант 3: Порівняння рядків Java з методом CompareTo

Існує також третій, менш поширений спосіб порівняння рядків Java, і це з методом String class CompareTo. Якщо два рядки абсолютно однакові, метод CompareTo поверне значення 0 (нуль). Ось короткий приклад того, як виглядає цей підхід для порівняння рядків:

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Поки я пишу про цю концепцію рівності на Java, важливо зазначити, що мова Java включає метод рівних у базовий клас Java Object. Щоразу, коли ви створюєте свої власні об'єкти і хочете надати засоби, щоб побачити, чи два екземпляри вашого об'єкта "рівні", вам слід перекривати (і реалізовувати) цей метод рівних у вашому класі (так само, як і мова Java ця поведінка рівності / порівняння у методі String дорівнює).

Ви можете переглянути це ==, .equals (), порівняти до () і порівняти ()


5
для рядкових літералів типу String string1 = "foo bar"; String string2 = "смуга foo"; ви можете безпосередньо використовувати оператор == для перевірки рівності вмісту
JAVA

1
У програмах google скрипт "CompareTo" не можливий. Я спробував встановити "рівний" Це єдине рішення, яке працює ....
user3887038

77

Функція:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

Тест:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);

6
Чим це відрізняється від інших відповідей? і чому це робити так, як ви пропонуєте
user151019

2
@Mark питання про різницю між ==і equalsвже відповів на інші рішення, я просто запропонував інший спосіб порівняння рядків у вільному шляху
Khaled.K

77

==Перевірка оператора , якщо дві посилання вказують на один і той же об'єкт чи ні. .equals()перевірити фактичний вміст рядка (значення).

Зауважимо, що .equals()метод належить до класу Object(суперклас усіх класів). Вам потрібно змінити його відповідно до вимог класу, але для String він уже реалізований, і він перевіряє, чи мають два рядки однакове значення чи ні.

  • Випадок 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    Причина: Строкові літерали, створені без нуля, зберігаються в пулі String в області permgen нагромадження. Отже, і s1, і s2 вказують на один і той же об'єкт у пулі.

  • Випадок 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    Причина: Якщо ви створюєте об'єкт String за допомогою newключового слова, на ньому виділяється окремий пробіл.


53

==порівнює опорне значення об'єктів, тоді як equals()метод, присутній у java.lang.Stringкласі, порівнює вміст Stringоб'єкта (з іншим об'єктом).


15
не бути вибагливим, але equals()метод для Stringнасправді в Stringкласі, а не в Object. Типовий параметр equals()у Objectне порівнював би те, що вміст однаковий, а насправді просто повертає істину, коли посилання є однаковим.
Джейкоб Шоен

1
@JacobSchoen: Наведене вище посилання більше не працює, коли GrepCode не працює. Ось альтернатива для рівного впровадження: [Inline Link] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Amandeep Singh

50

Я думаю, що коли ви визначаєте a, Stringви визначаєте об'єкт. Тому потрібно використовувати .equals(). Коли ви використовуєте примітивні типи даних, які ви використовуєте, ==але з String(і будь-яким об'єктом) ви повинні використовувати .equals().


7
"char []" - не примітивний тип даних! Це масив "char". І масиви самі по собі не примітивні типи даних.
Крістіан

48

Якщо equals()метод присутній у java.lang.Objectкласі, і очікується перевірка на еквівалентність стану об’єктів! Це означає вміст об’єктів. Тоді як== як очікується, оператор перевіряє, чи фактичні екземпляри об'єкта однакові чи ні.

Приклад

Розглянемо дві різні опорні змінні str1та str2:

str1 = new String("abc");
str2 = new String("abc");

Якщо ви використовуєте equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

Ви отримаєте вихід так, TRUEніби використовуєте ==.

System.out.println((str1==str2) ? "TRUE" : "FALSE");

Тепер ви отримаєте FALSEяк вихід, тому що обидва str1і str2вказують на два різні об'єкти, хоча вони обидва мають однаковий вміст рядка. Саме тому new String()щоразу створюється новий об’єкт.


43

Оператор == завжди призначений для порівняння посилань на об'єкт , тоді як метод порівняння .equals () класу String замінено для порівняння вмісту :

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)

40

Для всіх об'єктів гарантовано є .equals()метод, оскільки Object містить метод .equals(), який повертає булева. Завдання підкласу - перекрити цей метод, якщо потрібне додаткове визначення визначення. Без нього (тобто з використанням ==) лише два об'єкти пам'яті перевіряються між двома об'єктами на предмет рівності. Рядок переосмислює це.equals() метод, і замість використання адреси пам'яті він повертає порівняння рядків на рівні символів для рівності.

Ключова примітка полягає в тому, що рядки зберігаються в одному пуловому пакеті, тож після створення рядка він назавжди зберігається в програмі за тією ж адресою. Струни не змінюються, вони незмінні. Ось чому це погана ідея використовувати регулярне з'єднання рядків, якщо у вас є серйозна кількість обробних рядків. Замість цього ви б використовували StringBuilderнадані класи. Пам'ятайте, що вказівники на цей рядок можуть змінюватися, і якщо вам було цікаво побачити, чи два вказівники однакові, ==це був би прекрасний шлях. Самі струнні ні.


2
"Після створення рядка він назавжди зберігається в програмі за тією ж адресою" - Це неправильно. Лише постійні рядкові вирази часу компіляції (можливо, включаючи final Stringзмінні) та рядки, які ваша програма явно стажуються, зберігаються в тому, що ви називаєте "груповим пулом". Усі інші Stringоб'єкти підлягають збору сміття, коли на них більше немає живих посилань, як і на будь-який інший тип об’єктів. Крім того, хоча незмінність необхідна для роботи всього механізму інтернування, це в іншому випадку не має значення.
Тед Хопп

Порівняння рядків проводиться або через метод equalsIgnoreCase, який фактично порівнює вміст рядка. Але знак == просто перевірте опорні значення. Для рядкових літералів з пулових рядків у цьому випадку буде добре працювати. String s1 = new String ("a"); String s2 = new String ("a"); в цьому випадку s1 == s2 - помилково, але s1.equals (s2) - істина.
Шайлендра Сінгх

39

Ви також можете скористатися compareTo()методом порівняння двох рядків. Якщо результат сравнениеTo дорівнює 0, то два рядки рівні, інакше рядки, що порівнюються, не рівні.

The ==Порівнює посилання і не порівняти фактичні рядки. Якщо ви створили кожну рядок, використовуючи new String(somestring).intern()тоді, ви можете скористатися ==оператором для порівняння двох рядків, інакше рівняння () або порівняння Для використання можна лише методи.


35

У Java, коли оператор "==" використовується для порівняння двох об'єктів, він перевіряє, чи об'єкти відносяться до того самого місця в пам'яті. Іншими словами, він перевіряє, чи є в основному 2 імені об'єктів посиланнями на одне місце пам’яті.

Клас Java String фактично переосмислює реалізацію за замовчуванням equals () у класі Object - і він перекриває метод, щоб він перевіряв лише значення рядків, а не їх розташування в пам'яті. Це означає, що якщо ви покликаєте метод equals () для порівняння двох об'єктів String, то поки фактична послідовність символів однакова, обидва об'єкти вважаються рівними.

The == перевіряє оператор , якщо два рядки в точності той же об'єкт.

.equals()Перевірка методу , якщо два рядки мають однакове значення.


1
якщо один з них не є нульовим, оскільки s.equals (s2) вийде з ладу, якщо s є нульовим, що призведе до відмови порівняння. Звичайно, це насправді не суперечить відповіді; це просто застереження.
Джон Кумбс

1
Ні, він не вийде з ладу, він кине NullPointerException, внаслідок чого порівняння не відбудеться.
Bludzee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.