Тема 5. Работа со строками - BelyiZ/JavaCourses GitHub Wiki
Содержание:
Среди всех типов данных в Java особое внимание следует уделить типу String
, ведь он наиболее часто используется при
создании ПО. Для создания строк используются двойные кавычки, например:
String a = "I'm a string.";
Любой объект или примитив можно преобразовать в строку. Для ссылочных типов достаточно вызвать у них метод toString()
.
Примитивы можно сложить с пустой строкой. Примеры создания строк из других типов:
Integer a = 5;
double b = 1.5;
boolean c = false;
String d = a.toString();
String e = b + "";
String f = String.valueOf(c);
String g = a + "";
Операции со строками
Класс String не мутабельный, это значит, что создавать его наследников нельзя, а созданные объекты этого класса не меняют свое состояние в течение жизненного цикла. Именно по этой причине каждый метод вызванный у объекта строки не меняет сам объект, а создает новый, в котором размещает уже обработанный контент. Самый лучший способ познакомиться с доступными методами - заглянуть в документацию (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html).
Соединение строк
Такое поведение накладывает свои ограничения при написании кода. Например, объединение двух строк (конкатенация) приводит к созданию третьего объекта, куда будут скопированы данные из обеих строк.
Например, у нас есть две строки:
String a = “Hello”;
String b = “world”;
Даже если мы захотим заново использовать переменную "a", все равно будет создан новый объект. Так код
a = a + “ “ + b;
будет преобразован на момент компиляции в следующий:
a = new StringBuffer().append(a).append(new String(“ “)).append(b).toString();
Теперь наглядно видно, что происходит при конкатенации строк. Создается несколько новых объектов:
вспомогательный StringBuffer
(его мы рассмотрим позже) и два объекта String
.
А теперь представим, что конкатенация происходит в цикле:
for (int i = 0; i < 1000; i++) {
a = a + b:
}
Сколько лишних объектов создается в этом случае?
В Java есть два специальных класса: StringBuffer
и StringBuilder
- оба они предназначены, в том числе для решения подобных
проблем. Сначала собираем весь контент в одном объекте, а потом формирует экземпляр класса String
. Разница
между StringBuffer
и StringBuilder
в потокобезопасности. Первый может использоваться в многопоточной среде, второй -
нет.
Тогда, если мы перепишем код
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(b):
}
a = sb.toString();
то получим оптимальную версию. Именно так нужно работать со строками в циклах.
Сравнение строк
Строки, как и другие объекты нельзя сравнивать оператором "==". Такое сравнение подходит только для примитивов. Для объектов же проверка будет только на идентичность ссылок в кучу. Это значит, что два разных объекта String с одинаковым содержимым будут не эквивалентны относительно оператора сравнения. На практике иногда можно заметить обратное, например:
String a = "Reksoft";
String b = "Reksoft";
a == b; //true
Несмотря на то, что у нас два разных объекта, их сравнение вернет истину. Это происходит, потому что в Java существует
так называемый пул строк. Все строки-константы указанные в коде проекта помещаются в этот пул по мере выполнения кода во
время запуска приложения. Если при создании строки эквивалентное значение есть в пуле, то новый объект не создается, а
в переменную просто проставляется ссылка на ранее созданный. Таким образом и сравнение по ссылке будет возвращать true
. Объекты созданные явно через конструктор в пул строк не попадают.
Для правильного сравнения строк необходимо использовать метод .equals()
. Однако, существует еще ряд вспомогательных
методов, например, .equalsIgnoreCase()
, .contentEquals()
или Objects.equals()
.
Список литературы/курсов
- https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html
- https://metanit.com/java/tutorial/7.2.php
- http://study-java.ru/uroki-java/rabota-so-strokami-v-java-osnovnye-metody-klassa-string/
- http://proglang.su/java/strings
- https://gb.ru/geek_university/java
Тема 4. Управляющая логика | Оглавление | Тема 6. Введение в ООП