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

вы можете использовать методы CDI Producers. Он будет вызываться много раз, но результат первого вызова кэшируется в объеме компонента и эффективен для геттеров, которые вычисляют или инициализируют тяжелые объекты! См. здесь , для получения дополнительной информации.

726
задан Nathan H 23 January 2013 в 13:36
поделиться

10 ответов

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

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

Objects.equals () проверки на null прежде, чем звонить .equals(), таким образом, Вы не имеете к (доступный с JDK7, также доступного в [1 113] Гуава ).

String.contentEquals () сравнивает содержание String с содержанием любого CharSequence (доступный начиная с Java 1.5).

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

Вы почти [1 132] всегда хотят использовать Objects.equals(). В редкий ситуация, где Вы знаете , Вы имеете дело с [1 115], интернировал строки, Вы можете использование ==.

От [1 116] JLS 3.10.5. Строковые литералы :

, Кроме того, строковый литерал всегда относится к тот же экземпляр класса String. Это вызвано тем, что строковые литералы - или, в более общем плане, строки, которые являются значениями константных выражений ( В§15.28 ) - "интернируются", чтобы совместно использовать уникальные экземпляры, с помощью метода String.intern.

Подобные примеры могут также быть найдены в [1 118] JLS 3.10.5-1 .

5375
ответ дан 40 revs, 24 users 42% 24 January 2013 в 00:36
поделиться

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

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

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

100
ответ дан coobird 24 January 2013 в 00:36
поделиться

Я соглашаюсь с ответом от zacherates.

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

От zacherates примера:

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

, Если Вы интернируете равенство нелитеральной строки, true

new String("test").intern() == "test" ==> true 
100
ответ дан 3 revs, 3 users 83% 24 January 2013 в 00:36
поделиться
  • 1
    Второй вариант имеет побочный эффект, что он перезаписал бы позиционные параметры, как любой полученный от командной строки, или параметры передали функции (если эти строки в функции). Поэтому удостоверьтесь, что не полагались на 1$, 2$, и т.д. после использования набора - $input – Tuxdude 28 February 2013 в 07:42

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

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

Равняется, делает реальное сравнение для Вас.

126
ответ дан 2 revs, 2 users 89% 24 January 2013 в 00:36
поделиться

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

122
ответ дан 2 revs, 2 users 67% 24 January 2013 в 00:36
поделиться
  • 1
    Хорошо сделанный; я предлагаю предварительно ожидать set -f; к каждому set команда (примечание: должен быть отдельные команда), чтобы (временно) отключить расширение пути. Это гарантирует, что маркеры входа такой, поскольку * not' t случайно расширенный. – mklement0 11 April 2014 в 15:21

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

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

218
ответ дан 2 revs, 2 users 67% 24 January 2013 в 00:36
поделиться
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" в таблице строк. Ссылки отличаются, но содержание является тем же.

143
ответ дан duffymo 24 January 2013 в 00:36
поделиться
  • 1
    Превосходный! Спасибо за краткий и точный ответ! – user1940888 9 January 2013 в 21:36

== тестовые ссылки на объект, .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"));

следующее короче, но it’s менее очевидный, что оно проверяет на пустой указатель (от Java 7):

System.out.print(Objects.equals(fooString1, "bar"));
700
ответ дан 6 revs, 6 users 76% 24 January 2013 в 00:36
поделиться

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

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

, Который может помочь Вам.

98
ответ дан 3 revs, 3 users 64% 24 January 2013 в 00:36
поделиться

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

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

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

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

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

174
ответ дан 2 revs, 2 users 76% 24 January 2013 в 00:36
поделиться
  • 1
    довольный помочь, но don´ t забывают принимать ответ при нахождении его полезным! – sergio 17 January 2013 в 06:52
Другие вопросы по тегам:

Похожие вопросы: