Как сравнить строки в Java?

724

==До сих пор я использовал оператор в моей программе для сравнения всех своих строк. Тем не менее, я столкнулся с ошибкой, заменил одну из них .equals(), и она исправила ошибку.

Это ==плохо? Когда это должно и не должно быть использовано? Какая разница?

Натан Х
источник
12
Также полезно знать, что, если вы переопределяете метод .equals (), убедитесь, что вы переопределяете метод .hashcode (), в противном случае вы получите нарушающее отношение эквивалентности ч / б equals и hashcode. Для получения дополнительной информации обратитесь к документу Java.
Нагесваран
Оставьте ссылку на мое объяснение о том, почему ==работает так же, как на объектах: stackoverflow.com/a/19966154/2284641
Йоханнес Х.
==будет работать некоторое время, так как у Java есть пул строк, где он пытается повторно использовать ссылки на память часто используемых строк. Но ==сравнивает, что объекты равны, а не значения ... так .equals()что правильное использование вы хотите использовать.
Джеймс Оравец
Никогда не используйте ==, чтобы проверить, одинаковы ли строки, если вам не нравится выслеживать тонкие ошибки и изучать тонкости процесса интернирования Java String. "12"=="1"+2ложно (вероятно)
Рейс Одиссея

Ответы:

5564

== тесты на равенство ссылок (являются ли они одним и тем же объектом).

.equals() тесты на равенство значений (являются ли они логически «равными»).

Objects.equals () проверяет nullперед вызовом, .equals()поэтому вам не нужно (доступно с JDK7, также доступно в Гуаве ).

Следовательно, если вы хотите проверить, имеют ли две строки одинаковое значение, вы, вероятно, захотите использовать 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 и т. Д. В String перед выполнением сравнения на равенство, но оставляет проверку на нуль для вас.

Aaron Maenpaa
источник
3
Если == проверяет равенство ссылок, почему n == 5 имеет смысл? 5 не переменная
Хрит Рой
2
@HritRoy Потому что ==проверяет значение переменной. Когда у вас есть объект, переменная, которая ссылается на объект, имеет ссылку на объект в качестве значения . Таким образом, вы сравниваете ссылки при сравнении двух переменных с ==. При сравнении примитивного типа данных, такого как int, это все тот же случай. Переменная типа intимеет целочисленное значение. Таким образом, вы сравниваете значения двух intс помощью ==. Если 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
Whatsit
источник
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
Короткие методы для сравнения строк, которые могут содержать NULL, в Java: stackoverflow.com/questions/11271554/…
Вадим
5
@JonCoombs Java поддерживает создание подклассов и создание собственного метода. Однако некоторые классы помечены как окончательные по определенным причинам, поэтому String является одним из них, поэтому мы не можем расширять его. Мы можем создать другой класс и создать служебный класс, который будет принимать две строки в качестве аргументов и реализовывать нашу логику там. Также для проверки нуля некоторых других библиотек, таких как spring и apache, он хороший набор методов, можно использовать это.
Пантера
442

== сравнивает ссылки на объекты

.equals() сравнивает строковые значения

Иногда ==дает иллюзии сравнения значений String, как в следующих случаях:

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

Это связано с тем, что когда вы создаете какой-либо литерал String, JVM сначала ищет этот литерал в пуле String, и, если он найдет совпадение, эта же ссылка будет передана новой строке. Из-за этого мы получаем:

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

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

Однако происходит ==сбой в следующем случае:

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

В этом случае для new String("test") оператора будет создана новая строка в куче, и эта ссылка будет дана b, поэтому bбудет дана ссылка на кучу, а не в пул строк.

Теперь aуказывает на строку в пуле строк, а bуказывает на строку в куче. Из-за этого мы получаем:

если (a == b) ===> false.

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

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

Пока .equals() всегда сравнивает значение String, поэтому оно дает true в обоих случаях:

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 () сравнивает два экземпляра, но для их сравнения используется метод equals. Это может или не может быть сравнение вывода toString.
Джейкоб
3
@Jacob .equals()Метод класса объекта сравнивает экземпляры (ссылки / адреса), где .equals()методы класса String переопределяются для сравнения содержимого (символов)
Сатьядев
1
Хорошо бы выделить различия между пулами строк и Java-кучи, поскольку они, конечно, не одинаковы. В пуле строк Java пытается «кэшировать» Stringобъекты, чтобы сохранить объем памяти, Stringкоторый известен как неизменный (я надеюсь, что я говорю это правильно здесь). Также проверьте stackoverflow.com/questions/3052442/…
Роланд
1
Это ответ, который я искал.
Weezy
Какой отличный ответ!
alwbtc
223

В ==проверяет оператор , чтобы увидеть , если две строки в точности тот же объект.

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

Clayton
источник
5
Как правило, я настоятельно рекомендую библиотеку Apache Commons: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)
Марцин Эрбель
179

Строки в Java неизменны. Это означает, что всякий раз, когда вы пытаетесь изменить / модифицировать строку, вы получаете новый экземпляр. Вы не можете изменить исходную строку. Это было сделано для кэширования этих экземпляров строк. Типичная программа содержит множество строковых ссылок, и кэширование этих экземпляров может уменьшить объем используемой памяти и повысить производительность программы.

При использовании оператора == для сравнения строк вы не сравниваете содержимое строки, а фактически сравниваете адрес памяти. Если они оба равны, он вернет true и false в противном случае. Принимая во внимание, что равно в строке сравнивает содержимое строки.

Таким образом, вопрос в том, все ли строки кэшированы в системе, почему ==возвращается false, а equals возвращает true? Ну, это возможно. Если вы создаете новую строку, как String str = new String("Testing")вы, в конечном итоге вы создаете новую строку в кеше, даже если кеш уже содержит строку с таким же содержимым. Короче "MyString" == new String("MyString")всегда вернет false.

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

Примечание: оператор == намного быстрее, чем равен, просто потому, что вы сравниваете два адреса памяти, но вы должны быть уверены, что код не создает новые экземпляры String в коде. В противном случае вы столкнетесь с ошибками.

Faisal Feroz
источник
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()метод делает символ за символом сравнения содержимого.

Когда вы вызываете new для aand b, каждый получает новую ссылку, которая указывает на "foo"таблицу строк. Ссылки разные, но содержание одинаковое.

duffymo
источник
128

Да, это плохо ...

==означает, что ваши две строковые ссылки - это один и тот же объект. Возможно, вы слышали, что это так, потому что Java хранит своего рода буквальную таблицу (что она делает), но это не всегда так. Некоторые строки загружаются по-разному, создаются из других строк и т. Д., Поэтому вы никогда не должны предполагать, что две одинаковые строки хранятся в одном месте.

Равный делает реальное сравнение для вас.

Uri
источник
124

Да, ==это плохо для сравнения строк (любые объекты на самом деле, если вы не знаете, что они канонические). ==просто сравнивает ссылки на объекты. .equals()тесты на равенство. Для строк часто они будут одинаковыми, но, как вы обнаружили, это не гарантируется всегда.

cletus
источник
118

У Java есть пул String, в котором Java управляет выделением памяти для объектов String. Посмотрите Струнные Бассейны на Яве

Когда вы проверяете (сравниваете) два объекта с помощью ==оператора, он сравнивает равенство адресов в пуле строк. Если два объекта 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
Saurabh Agarwal
источник
7
Я вижу, что это поздний ответ на большой вопрос. Могу ли я спросить, что это дает, что еще не упоминалось в существующих ответах?
Мистик
6
@Mysticial он добавил, equalsIgnoreCaseчто может быть информативным для более свежего.
AmitG
103

Я согласен с ответом от zacherates.

Но то, что вы можете сделать, это вызвать intern()ваши не буквальные строки.

Из примера zacherates:

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

Если вы интернируете не буквальное равенство строк true:

new String("test").intern() == "test" ==> true 
pgras
источник
8
Это вообще не очень хорошая идея. Стажировка является относительно дорогой и может (как это ни парадоксально) >> увеличить << объем используемой памяти JVM и увеличить затраты на сборку мусора. В большинстве случаев они перевешивают преимущества производительности при использовании ==для сравнения строк.
Стивен С,
101

==сравнивает ссылки на объекты в Java , и это не исключение для Stringобъектов.

Для сравнения фактического содержимого объектов (в том числе String) необходимо использовать equalsметод .

Если сравнение двух Stringобъектов с использованием ==оказывается true, то это потому, что Stringобъекты были интернированы, и виртуальная машина Java имеет несколько ссылок указывают на один и тот же экземпляр String. Не следует ожидать, что сравнение одного Stringобъекта, содержащего то же содержимое, что и другой Stringобъект, используется ==для оценки как true.

coobird
источник
99

.equals()сравнивает данные в классе (при условии, что функция реализована). ==сравнивает местоположение указателя (расположение объекта в памяти).

==возвращает значение true, если оба объекта (НЕ ОБРАЩАЯСЯ О ПРИМИТИВАХ) указывают на тот же экземпляр объекта. .equals()возвращает true, если два объекта содержат одинаковые данные в equals()сравнении ==с Java

Это может помочь вам.

Мэтт Разза
источник
95

==выполняет проверку равенства ссылок, ссылаются ли 2 объекта (в данном случае строки) на один и тот же объект в памяти.

equals()Метод будет проверять ли содержимое или же состояния из 2 -х объектов являются одинаковыми.

Очевидно, ==это быстрее, но во многих случаях будет (может) давать ложные результаты, если вы просто захотите сказать, если 2 Strings содержат один и тот же текст.

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

Не беспокойтесь о производительности. Некоторые вещи, чтобы поощрить использование String.equals():

  1. Реализация String.equals()первых проверок на равенство ссылок (с использованием ==), и если 2 строки одинаковы по ссылке, дальнейшие вычисления не выполняются!
  2. Если 2 строковые ссылки не совпадают, String.equals()далее проверим длину строк. Это также быстрая операция, потому что Stringкласс хранит длину строки, не нужно подсчитывать символы или кодовые точки. Если длины различаются, дальнейшая проверка не выполняется, мы знаем, что они не могут быть равны.
  3. Только если мы дошли до этого уровня, будет фактически сопоставлено содержимое 2 строк, и это будет кратким сравнением: не все символы будут сравниваться, если мы обнаружим несовпадающий символ (в той же позиции в 2 строках ), дальнейшие символы проверяться не будут.

Когда все сказано и сделано, даже если у нас есть гарантия того, что строки являются интернами, использование equals()метода по-прежнему не так затратно, как можно подумать, определенно рекомендуемый способ. Если вам нужна эффективная проверка ссылок, используйте перечисления, если в спецификации и реализации языка гарантируется, что одно и то же значение перечисления будет одним и тем же объектом (посредством ссылки).

icza
источник
2
Obviously == is faster- на самом деле реализация .equals(String)первых проверок ==прежде всего, поэтому я бы сказал, что скорость примерно одинакова.
Раззл Шазл
2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Раззл Шазл
82

Если вы похожи на меня, когда я впервые начал использовать Java, я хотел использовать оператор "==", чтобы проверить, равны ли два экземпляра String, но, что бы там ни было, это неправильный способ сделать это в Java.

В этом уроке я продемонстрирую несколько разных способов правильного сравнения строк Java, начиная с подхода, который я использую большую часть времени. В конце этого руководства по сравнению строк Java я также расскажу, почему оператор "==" не работает при сравнении строк Java.

Вариант 1. Сравнение строк Java с методом equals В большинстве случаев (возможно, в 95% случаев) я сравниваю строки с методом equals класса Java String, например:

if (string1.equals(string2))

Этот метод String equals просматривает две строки Java, и если они содержат одинаковую строку символов, они считаются равными.

Взглянув на пример быстрого сравнения строк с помощью метода equals, если бы был выполнен следующий тест, две строки не были бы признаны равными, поскольку символы не совпадают (случай символов отличается):

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.")
}

Но когда две строки содержат одинаковую строку символов, метод equals вернет true, как в этом примере:

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 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 включает метод equals в базовый класс Java Object. Всякий раз, когда вы создаете свои собственные объекты и хотите предоставить средство, чтобы увидеть, равны ли два экземпляра вашего объекта, вы должны переопределить (и реализовать) этот метод equals в вашем классе (так же, как язык Java обеспечивает это равенство / поведение сравнения в методе String equals).

Возможно, вы захотите взглянуть на это ==, .equals (), compareTo () и сравнить ()

Mohamed E. ManSour
источник
5
для строковых литералов, таких как String string1 = "foo bar"; String string2 = "foo bar"; Вы можете напрямую использовать оператор == для проверки равенства контента
JAVA
1
В приложениях Google скрипт «Сравнить» невозможен. Я попробовал установить "равно" Это было единственное решение, которое работает ....
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);
Khaled.K
источник
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

    Причина: строковые литералы, созданные без нуля, хранятся в пуле строк в области 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ключевого слова, ему выделяется отдельное пространство в куче.

Aniket Thakur
источник
53

==сравнивает эталонное значение объектов, тогда как equals()метод, присутствующий в java.lang.Stringклассе, сравнивает содержимое Stringобъекта (с другим объектом).

самкит шах
источник
15
не быть придирчивым, но equals()метод на Stringсамом деле в Stringклассе, а не в Object. Значение по умолчанию для equals()in Objectне будет сравнивать, что содержимое одинаково, и на самом деле просто возвращает true, когда ссылка одинакова.
Джейкоб Шон
1
@JacobSchoen: приведенная выше ссылка больше не работает, так как GrepCode не работает. Вот альтернатива для равной реализации: [Встроенная ссылка] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
Амандип Сингх
50

Я думаю, что когда вы определяете, Stringвы определяете объект. Так что вам нужно использовать .equals(). Когда вы используете примитивные типы данных, которые вы используете, ==но с String(и любым объектом) вы должны использовать .equals().

fabricioflores
источник
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

Оператор == всегда предназначен для сравнения ссылок на объекты , тогда как метод класса String .equals () переопределяется для сравнения содержимого :

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)
sham.y
источник
40

Все объекты гарантированно имеют .equals()метод, поскольку Object содержит метод .equals(), который возвращает логическое значение. Задача подкласса - переопределить этот метод, если требуется дополнительное определение. Без этого (т.е. с использованием ==) только адреса памяти проверяются между двумя объектами на равенство. Строка переопределяет этот .equals()метод и вместо использования адреса памяти возвращает сравнение строк на уровне символов для равенства.

Ключевым моментом является то, что строки хранятся в одном единственном пуле, поэтому после создания строки она всегда сохраняется в программе по одному и тому же адресу. Строки не меняются, они неизменны. Вот почему плохая идея использовать обычную конкатенацию строк, если у вас есть серьезный объем обработки строки. Вместо этого вы бы использовали StringBuilderпредоставленные классы. Помните, что указатели на эту строку могут меняться, и если вам интересно узнать, совпадают ли два указателя, это ==будет хорошим способом. Сами струны нет.

Джеймс
источник
2
«как только строка создана, она навсегда сохраняется в программе по одному и тому же адресу» - это совершенно неверно. Только константные строковые выражения времени компиляции (возможно, включающие final Stringпеременные) и строки, которые ваша программа явно интернирует, хранятся в том, что вы называете «объединенным пулом». Все другие Stringобъекты подлежат сборке мусора, если на них больше нет живых ссылок, как и любой другой тип объекта. Кроме того, хотя для работы всего интернирующего механизма требуется неизменность, в остальном это не имеет значения.
Тед Хопп
Сравнение строк выполняется с помощью метода equalsIgnoreCase, который на самом деле сравнивает содержимое строки. Но == знак просто проверьте контрольные значения. Для строковых литералов из пула строк будет хорошо работать в этом случае. String s1 = новая строка ("a"); String s2 = новая строка ("a"); в этом случае s1 == s2 ложно, но s1.equals (s2) верно.
Шайлендра Сингх
39

Вы также можете использовать compareTo()метод для сравнения двух строк. Если результат CompareTo равен 0, тогда две строки равны, иначе сравниваемые строки не равны.

==Сравнивает ссылки и не сравнить фактические строки. Если вы создали каждую строку, используя, new String(somestring).intern()то вы можете использовать ==оператор для сравнения двух строк, в противном случае можно использовать только методы equals () или compareTo.

AlvaroAV
источник
35

В Java, когда оператор «==» используется для сравнения 2 объектов, он проверяет, ссылаются ли объекты на одно и то же место в памяти. Другими словами, он проверяет, являются ли два имени объекта в основном ссылками на одну и ту же ячейку памяти.

Класс Java String фактически переопределяет реализацию equals () по умолчанию в классе Object - и он переопределяет метод так, что он проверяет только значения строк, а не их расположение в памяти. Это означает, что если вы вызываете метод equals () для сравнения двух строковых объектов, то при условии, что фактическая последовательность символов равна, оба объекта считаются равными.

== проверяет оператор , если две строки в точности тот же объект.

.equals()Проверка метода , если две строки имеют одинаковое значение.

Lijo
источник
1
если только один из них не равен нулю, так как s.equals (s2) завершится сбоем, если s равно нулю, что приведет к сбою сравнения. Конечно, это на самом деле не противоречит ответу; это просто предостережение.
Джон Кумбс
1
Нет, это не приведет к сбою, оно вызовет исключение NullPointerException, в результате чего сравнение не будет выполнено.
Блудзи