Подтвердить что ты не робот

Ссылки на строки в java

Возможный дубликат:
Сравнение строк и интернирование строк в Java

Я пытаюсь запустить следующий код в java:

if("hello".trim() == "hello".trim())
   System.out.println("Equal");
else
   System.out.println("Not Equal");

и он печатает равно. Я понимаю, что в этом случае обе строки имеют одинаковую ссылку. Но когда я пытаюсь сделать то же самое, просто добавив пробел в обе строки, он печатает "Не равно".

if("hello ".trim() == "hello ".trim())
   System.out.println("Equal");
else
  System.out.println("Not Equal");

Может ли кто-нибудь объяснить, почему я получаю "Не равный"...?

4b9b3361

Ответ 1

Просто проверьте реализацию trim, и вам будет ясно. Если trim определяет, что строка не имеет начального/конечного пробела, она возвращает ту же строку — это ваш первый случай. Во втором случае создается новая строка, поэтому у вас есть два равных экземпляра String, каждый со своим собственным идентификатором. И, как мне кажется, вы знаете, оператор == сравнивает ссылки, а не объекты, поэтому не имеет значения, представляют ли эти два экземпляра одинаковые строки или нет.

Ответ 2

Это поведение описано в JavaDoc trim() (жирный мины):

Копия этой строки с удалением ведущего и конечного пробелов удалена, или эта строка, если она не имеет пробелов в начале или конце.

Это также ясно из реализации:

public String trim() {
    //...
    return ((st > 0) || (len < count)) ? substring(st, len) : this;
}

Если были обнаружены некоторые ведущие или завершающие пробелы, substring() вызывается, возвращая новый String. this возвращается иначе.

Интересный факт: в обоих случаях (если this возвращается и когда вызывается substring()), возвращаемые объекты указывают на тот же исходный массив char[]. Изменяется только объект обтекания String, а индексы массива выбирают подмножество этого массива.

Ответ 3

if("hello".trim() == "hello".trim())

Здесь ваша строка фактически не изменена. тогда как во втором случае: -

if("hello ".trim() == "hello ".trim())

Вы изменяете строку. И обе строки создают разные объекты.

Хотя, если вы попытаетесь сравнить их с помощью метода equals(), вы получите результат по желанию. Поскольку метод equals() сравнивает содержимое двух строк, тогда как == сравнивает ссылку..

Итак, когда два разных объекта строк с одинаковым содержимым сравниваются с помощью ==, вы фактически сравниваете reference этих строк, которые различны.

Ответ 4

Из документации - Обрезка:

"Если этот объект String представляет собой пустую последовательность символов, или первый и последний символы последовательности символов, представленные этим объектом String, имеют коды больше, чем '\ u0020' (символ пробела), то ссылка на этот объект String возвращается."

(в случае вашего первого примера вы получите ту же ссылку)

"В противном случае пусть k - индекс первого символа в строке, чей код больше, чем '\ u0020', и пусть m - индекс последнего символа в строке, код которой больше, чем '\ u0020' Создается новый объект String, представляющий подстроку этой строки, которая начинается с символа с индексом k и заканчивается символом с индексом m, т.е. Результатом this.substring(k, m + 1)."

(так, создаются две новые строки, решение возвращает false, поскольку два объекта в памяти различаются)

Для справки в будущем вы можете сделать это: if ("hello ".trim().equals("hello ".trim())), чтобы проверить, равно ли содержимое двух строк.