— Привет, Амиго. Сегодня мы разберем ещё несколько самых частых сценариев работы со строками. Например, ты знаешь, как разбить строку на несколько частей?
— Сходу не скажу, Элли. Но ты ведь расскажешь?
Метод split()
— Для этого есть несколько способов. Первый способ разбить строку на несколько частей — использовать метод split()
. В него в качестве параметра нужно передать регулярное выражение: специальный шаблон строки-разделителя. Что такое регулярное выражение, вы узнаете в квесте Java Collections.
Пример:
Код | Результат |
---|---|
|
Результатом будет массив из трех строк:
|
Просто, но иногда такой подход избыточен. Если разделителей много, например, «пробел», «enter», «таб», «точка», приходится конструировать достаточно сложное регулярное выражение.
— Ну да. А если сложно читать, значит, сложно вносить изменения.
Класс StringTokenizer
— В Java есть специальный класс, вся работа которого — разделять строку на подстроки.
— Этот класс не использует регулярные выражения: вместо этого в него просто передается строка, состоящая из символов-разделителей. Преимущества этого подхода в том, что он не разбивает сразу всю строку на кусочки, а потихоньку идет от начала к концу.
Класс состоит из конструктора и двух методов. В конструктор нужно передать строку, которую мы разбиваем на части, и строку — набор символов, используемых для разделения.
Методы | Описание |
---|---|
|
Возвращает следующую подстроку |
|
Проверяет, есть ли еще подстроки. |
— Этот класс мне чем-то напомнил класс Scanner, у которого тоже были методы nextLine()
и hasNextLine()
.
— Хорошая ассоциация. Создать объект StringTokenizer
можно командой:
StringTokenizer имя = new StringTokenizer(строка, разделители);
Где строка — это строка, которую будем делить на части. А разделители — это строка, каждый символ которой считается символом-разделителем. Пример:
Код | Вывод на экран |
---|---|
|
|
— Обрати внимание, что разделителем считается каждый символ строки, переданный второй строкой в конструктор StringTokenizer
.
Метод String.format()
и класс StringFormatter
— Ещё один интересный метод класса String — format()
.
— Допустим, у тебя есть различные переменные с данными. Как вывести их на экран одной строкой? Например, у нас есть данные (левая колонка) и желаемый вывод (правая колонка):
Код | Вывод на экран |
---|---|
|
|
Код такой программы будет выглядеть примерно так:
Код программы |
---|
|
— Согласись, код не слишком читабельный. Более того, если бы имена переменных были длиннее, код стал бы еще сложнее:
Код программы |
---|
|
— Да, читается так себе!
— Не переживай, в реальных программах такая ситуация встречается часто, поэтому я хочу рассказать о способе, как проще и короче записать этот код.
String.format
— У класса String
есть статический метод format()
: он позволяет задать шаблон объединения строки с данными. Общий вид этой команды такой:
String имя = String.format(шаблон, параметры);
Пример:
Код | Результат |
---|---|
|
|
|
|
|
|
— В метод format()
первым параметром передают строку-шаблон, которая содержит весь нужный текст, а в местах, где нужно вставлять данные, написаны специальные символы типа %d
, %s
и т.п.
— Вот эти %s
и %d
метод format()
и заменяют на параметры, которые идут следом за строкой-шаблоном. Если нужно подставить строку, мы пишем %s
, если число — %d
. Пример:
Код | Результат |
---|---|
|
s будет равна "a=1, b=4, c=3" |
— Вот краткий список параметров, которые можно использовать внутри шаблона:
Символ | Обозначение |
---|---|
|
String |
|
целое число: byte , short , int , long |
|
вещественное число: float , double |
|
boolean |
|
char |
|
Date |
|
Символ % |
— Эти параметры указывают на тип данных, но есть еще параметры, которые указывают на порядок данных. Чтобы взять параметр по его номеру (нумерация начинается с единицы), нужно записать «%1$d» вместо «%d». Пример:
Код | Результат |
---|---|
|
s будет равна "a=13, b=12, c=11" |
%3$d
возьмет 3-й параметр-переменную, %2$d
возьмет второй параметр. %d
возьмет самый первый параметр-переменную. Параметры шаблона %s
, %d
обращаются к переменным-параметрам независимо от параметров шаблона типа %3$d
или %2$s
String Pool
Фрагмент лекции JavaRush - университета.
— Все строки, которые были заданы в коде в виде литералов, во время работы программы хранятся в памяти в так называемом StringPool
. StringPool
— это специальный массив для хранения строк. Цель его создания — оптимизация хранения строк:
— Во-первых, строки, заданные в коде, нужно все-таки где-то хранить. Код — это команды, а данные (тем более такие большие как строки) нужно хранить в памяти отдельно от кода. В коде фигурируют только ссылки на объекты-строки.
— Во-вторых, все одинаковые литералы можно хранить в памяти только один раз. Так оно и работает. Когда код твоего класса загружается Java-машиной, все строковые литералы добавляются в StringPool
, если их там еще нет. Если уже есть, просто используется ссылка на строку из StringPool
.
Поэтому если в своем коде ты присвоишь нескольким String-переменным одинаковые литералы, переменные будут содержать одинаковые ссылки. В StringPool
литерал будет добавлен только один раз, во всех остальных случаях будет браться ссылка на уже загруженную в StringPool
строку.
Как это примерно работает:
Код | Работа с StringPool |
---|---|
|
|
— Именно поэтому переменные a
и b
будут хранить одинаковые ссылки.
— Надеюсь, понял всё правильно.
Метод intern()
.
— Ну и самое интересное: ты можешь программно добавить любую строку в StringPool
. Для этого нужно просто вызвать метод intern()
у String
-переменной.
— Метод intern()
добавит строку в StringPool
, если ее еще там нет, и вернет ссылку на строку из StringPool
.
— А что будет, если в StringPool
добавить с помощью метода intern()
две идентичные строки?
— Метод вернет одинаковые ссылки. Это можно использовать чтобы сравнивать строки по ссылке. Пример:
Код | Примечание |
---|---|
|
|
|
|
Вряд ли ты будешь часто пользоваться этим методом. Однако о нем любят спрашивать на собеседованиях.
— Поэтому лучше о нем знать, чем не знать. Спасибо, Элли!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ