Java
  • Java
  • Основы языка
    • Типы данных
    • Литералы
    • Переменные и константы
    • Операторы
    • Управляющие последовательности
  • Модификаторы
    • Модификаторы доступа
    • Модификаторы используемые не для доступа
  • Ввод с клавиатуры
  • Особенности строк
  • Коллекции
    • ArrayList и LinkedList
    • Set и Map
  • Дата и время
  • Исключения
    • Встроенные исключения
  • Интерфейсы
    • Абстрактный класс vs. интерфейс
  • Оператор instanceof
Powered by GitBook
On this page
  • Сравнение строк
  • Метод String.intern()
Edit on GitHub

Особенности строк

class String

PreviousВвод с клавиатурыNextКоллекции

Last updated 3 years ago

Сравнение строк

Для сравнения строк ВСЕГДА используй метод equals()! Сравнивая строки, ты почти всегда имеешь в виду сравнение их текста, а не ссылок, областей памяти и прочего.

Метод equals() делает именно то, что тебе нужно.

Оператор == сравнивает ссылки.

Метод equals сравнивает значения.

Следовательно, если вы хотите сравнить строки на равенство, следует использовать equals.

Однако в некоторых случаях строки гарантированно представлены одним и тем же объектом благодаря (). Эти случаи явно описаны в .

Пул строк — область для хранения всех строковых значений, которые ты создаешь в своей программе.

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

// Эти строки имеют одно и тоже же значение
new String("test").equals("test") // --> true 

// ...но это разные объекты
new String("test") == "test" // --> false 

// ...эти строки тоже разные объекты
new String("test") == new String("test") // --> false 

// ...но эти строки указывают на один и тот же объект,
// потому что компилятор добавляет все литералы в пул.
"test" == "test" // --> true 

// Конкатенация литералов тоже происходит на стадии компиляции,
// поэтому они указывают на один объект
"test" == "te" + "st" // --> true

// но вызов substring() происходит во время выполнения,
// в результате получаются разные объекты.
"test" == "!test".substring(1) // --> false

// Строки из пула могут быть получены с помощью вызова intern().
"test" == "!test".substring(1).intern() // --> true

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

Остерегайтесь вызова equals на null! Оператор == прекрасно сравнивает строки, если одна или более из них равна null, но вызов метода equals на строке, равной null, приведёт к исключению.

Для сравнения строк, которые могут быть равны null, вы можете воспользоваться следующим методом:

public static boolean equals(String str1, String str2) {
    return str1 == null ? str2 == null : str1.equals(str2);
}

Он присутствует в некоторых сторонних библиотеках, например, в Apache Commons.

Если вы пользуетесь современными средами разработки, то они предупредят, если вы попытаетесь сравнить строки с помощью оператора ==. Всегда обращайте внимание на подобные предупреждения.

Метод String.intern()

У класса String есть еще один хитрый метод — intern(); Метод intern() напрямую работает со String Pool’ом. Если ты вызываешь метод intern() у какой-то строки, он:

  • Смотрит, есть ли строка с таким текстом в пуле строк

  • Если есть — возвращает ссылку на нее в пуле

  • Если же нет — помещает строку с этим текстом в пул строк и возвращает ссылку на нее.

Применив метод intern() к ссылке на строку, которая создавалась через new, мы можем сравнивать ее со ссылкой на строку из String Pool’a через оператор ==.

public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush - лучший сайт для изучения Java!";
       String s2 = new String("JavaRush - лучший сайт для изучения Java!");
       System.out.println(s1 == s2.intern());
   }
}

Вывод в консоль:

true

Раньше, когда мы сравнивали их без intern(), результат был равен false. Теперь же метод intern() проверил, есть ли строка с текстом "JavaRush — лучший сайт для изучения Java!" в пуле строк. Разумеется, она там есть: мы создали ее, когда написали

String s1 = "JavaRush — лучший сайт для изучения Java!";

Была проведена проверка, что ссылка s1 и ссылка, возвращенная методом s2.intern() указывают на одну область в памяти, и, конечно, так оно и есть:)

пулу строк
string interning
спецификации языка Java