1. Клас StringTokenizer

Є ще кілька сценаріїв, які дуже часто використовуються для роботи з рядками. Як розділити рядок на частини? Для цього є декілька способів.

Метод split()

Найпростіший спосіб розділити рядок на кілька частин — це скористатися методом split(). У нього потрібно передати як параметр регулярний вираз: спеціальний шаблон рядка-роздільника. Що таке регулярний вираз, ви дізнаєтеся у квесті Java Multithreading.

Приклад:

Код Результат
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
Результатом буде масив із трьох рядків:
["Good ", "ws everyo", "!"]

Це простий спосіб, але часом такий підхід є надмірним. Якщо роздільників багато, наприклад «пробіл», «enter», «tab», «крапка», доводиться конструювати досить складний регулярний вираз. Його складно читати, отож у нього складно вносити зміни.

Клас StringTokenizer

У мові Java є спеціальний клас, призначений саме для розділення рядків на підрядки.

Цей клас не використовує регулярні вирази, натомість в нього просто передається рядок, який складається із символів-роздільників. Переваги цього підходу в тому, що рядок не відразу розбивається на шматочки, а поступово аналізується від початку до кінця.

Клас складається з конструктора і двох методів. У конструктор передається рядок, який потрібно розбити на частини, і рядок — набір символів, які використовуються як роздільники.

Методи Опис
String nextToken()
Повертає наступний підрядок
boolean hasMoreTokens()
Перевіряє, чи немає ще підрядків.

Цей клас трохи нагадує клас Scanner, який теж має методи nextLine() і hasNextLine().

Для створення об'єкта StringTokenizer використовують таку команду:

StringTokenizer ім'я = new StringTokenizer(рядок, роздільники);

де рядок — це рядок, який потрібно розділити на частини; а роздільники — це рядок, кожний символ в якому вважається символом-роздільником. Приклад:

Код Виведення на екран
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

Зауважте, що кожен символ у другому рядку, переданому в конструктор StringTokenizer, вважається роздільником.


6
Задача
Модуль 1. Java Syntax,  13 рівень1 лекція
Недоступна
Створімо хмарочос
Спробуймо спорудити свій перший хмарочос і оголосити про результат виконання в консолі. Для цього тобі потрібно викликати конструктор класу Skyscraper в методі main і в тілі конструктора вивести в консоль текст "Хмарочос побудовано.".

2. Метод String.format() і клас StringFormatter

Клас String має ще один цікавий метод — format().

Припустімо, у вас є різні змінні з даними. Як вивести їх на екран одним рядком? Наприклад, маємо дані (лівий стовпець), які ми хочемо вивести на екран у певному вигляді (правий стовпець):

Код Виведення на екран
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

Ваш код матиме приблизно такий вигляд:

Код програми
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

Такий код не дуже зручно читати. А якби імена змінних були довшими, код став би ще складнішим:

Код програми
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

Не дуже зручно читати, чи не так?

Проте в реальних програмах така ситуація трапляється досить часто, тому я розповім, як спростити й скоротити цей код.

String.format

Клас String має статичний метод format(): він дає змогу визначити шаблон об'єднання рядка з даними. Загальний вигляд цієї команди такий:

String ім'я = String.format(шаблон, параметри);

Приклад:

Код Результат
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

У метод format() першим параметром передається рядок-шаблон, який містить увесь потрібний текст, а в ті місця, куди потрібно вставити дані, вписано спеціальні символи типу %d, %s тощо.

Метод format() замінює ці символи %s і %d на параметри, вказані після рядка-шаблону. Коли потрібно підставити рядок, пишемо %s, а коли число — %d. Приклад:

Код Результат
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
s дорівнюватиме "a=1, b=4, c=3"

Скорочений перелік параметрів, які можна використовувати в шаблоні:

Символ Позначення
%s
String
%d
ціле число: byte, short, int, long
%f
дійсне число: float, double
%b
boolean
%c
char
%t
Date
%%
Символ %

Ці параметри вказують на тип даних, але є такі параметри, які вказують на порядок даних. Для того щоб вибрати параметр за номером (нумерація починається з одиниці), потрібно написати %1$d замість %d. Приклад:

Код Результат
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
s дорівнюватиме "a=13, b=12, c=11"

Замість %3$d підставиться 3-й параметр-змінна, замість %2$d — 2-й параметр-змінна, а замість %d — найперший параметр-змінна. Параметри шаблону %s, %d звертаються до параметрів-змінних незалежно від параметрів шаблону типу %3$d або %2$s.


6
Задача
Модуль 1. Java Syntax,  13 рівень1 лекція
Недоступна
Збудуймо новий житловий комплекс JavaRush Towers
Спробуймо побудувати житловий комплекс із трьох висоток. Для цього ми будемо використовувати три різні способи виведення інформації: Оголошує про результат будівництва. Оголошує про результат і вказує кількість поверхів. Оголошує про результат і вказує забудовника. Приклад виведення: Хмарочос побудо

3. String Pool

Усі рядки, що задано в коді як літерали, під час роботи програми зберігаються в пам'яті в особливому місці, яке має назву StringPool. StringPool — це спеціальний простір, створений для оптимізації зберігання рядків.

По-перше, рядки, визначені в коді, потрібно десь зберігати. Код — це команди, а дані (зокрема такі великі, як рядки) потрібно зберігати в пам'яті окремо від коду. У коді використовуються тільки посилання на об'єкти-рядки.

По-друге, можна усі однакові літерали зберегти в пам'яті лише один раз. Отак воно й працює. Коли код вашого класу завантажується Java-машиною, усі рядкові літерали додаються до StringPool (якщо їх там ще немає). Якщо такий рядок у StringPool вже є, просто використовується посилання на цей рядок.

Тому, якщо в коді присвоїти декільком змінним типу String однакові літерали, ці змінні будуть містити однакові посилання. У StringPool літерал додається тільки один раз, у решті випадків буде використовуватися посилання на рядок, уже завантажений у StringPool.

Отак це працює:

Код Робота зі StringPool
String a = "Привіт";
String b = "Привіт";
String c = "Бувай";
String[] pool = {"Привіт", "Бувай"};
a = pool[0];
b = pool[0];
c = pool[1];

Саме тому змінні a і b зберігатимуть однакові посилання.

Метод intern()

І найцікавіше: будь-який рядок можна програмним шляхом додати до StringPool. Для цього потрібно просто викликати для змінної типу String метод intern().

Метод intern() додасть рядок до StringPool, якщо його там ще немає, і поверне посилання на рядок зі StringPool.

Якщо за допомогою методу intern() додати до StringPool два ідентичних рядки, метод поверне однакові посилання. Цим можна користуватися для порівняння рядків за посиланнями. Приклад:

Код Примітка
String a = new String("Привіт");
String b = new String("Привіт");
System.out.println(a == b);


false
String a = new String("Привіт");
String b = new String("Привіт");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

Навряд чи ви часто використовуватимете цей метод, проте про нього зазвичай запитують на співбесідах, тож його варто знати.


6
Задача
Модуль 1. Java Syntax,  13 рівень1 лекція
Недоступна
Збудуймо новий бізнес-комплекс JavaRush Business Center
Спробуймо побудувати бізнес-центр, який складається з двох будівель: одну з них тільки починаємо будувати, а друга перебуває на етапі планування, тому про неї мало що відомо. Тобі потрібно створити два конструктори: один з параметрами, другий — без. Обидва вони мають ініціалізувати поля floorsCount