Java: Цепочки вызовов методов
Обработка данных может состоять из большого количества шагов, которые нужно выполнить один за другим.
Возьмем для примера такую задачу: сформировать адрес страницы в интернете на основе введенного пользователем названия статьи. Такая задача часто возникает при публикации статей в блогах. Подобные адреса выглядят так:
https://ru.hexlet.io/blog/posts/iz-vahtovika-v-programmirovanieПоследняя часть здесь iz-vahtovika-v-programmirovanie создана автоматически кодом, который мы написали на Хекслете. У нее есть специальное название — это слаг.
Какие шаги нужно выполнить, чтобы получить подобную строку? Вот лишь некоторые из них:
- Перевести все в нижний регистр, чтобы случайно не создавались дубли одинаковых страниц в поисковых системах
- Очистить название от пробельных символов по краям. Они могут случайно появиться при вводе
- Выполнить транслитерацию, потому что в адресах лучше использовать символы латинского алфавита
- Вырезать специальные символы вроде вопросительных и восклицательных знаков
- Заменить пробелы на дефисы
Часть шагов требует новых для нас знаний, поэтому мы их опустим. Остальные шаги будут выглядеть примерно так:
// Название, введенное пользователем. Для простоты на английском
var name = " How much is the fish? \n";
// вырезаем концевые пробелы и перенос строки
name = name.trim();
// Удаляем вопрос
name = name.replace("?", "");
// Заменяем пробелы на дефис
name = name.replace(" ", "-");
// Переводим в нижний регистр
name = name.toLowerCase();
System.out.println(name); // => how-much-is-the-fishЕсли внимательно посмотреть на этот код, то можно заметить общий шаблон. Метод возвращает данные, которые мы присваиваем переменной, и дальше по цепочке обрабатываем их.
Цепочка методов
Этот шаблон можно упростить, убрав промежуточное перезаписывание переменной. Метод возвращает новую строку, и к этой строке сразу применяется следующий метод. Такой прием называют цепочкой методов (method chaining).
var name = " How much is the fish? ";
name = name.trim().replace("?", "").replace(" ", "-").toLowerCase();
System.out.println(name); // => how-much-is-the-fishМетоды вызываются один за другим, как звенья в цепочке. Это позволяет писать компактный и читаемый код. Если цепочка становится слишком длинной, ее можно разбить на несколько строк:
name = name.trim()
.replace("?", "")
.replace(" ", "-")
.toLowerCase();Несмотря на удобство этого механизма, им не стоит злоупотреблять. Промежуточные переменные иногда упрощают понимание кода.
Порядок вычисления
В цепочке методов порядок выполнения идет слева направо. Каждый следующий метод вызывается на результате предыдущего:
var text = " hExLeT ";
System.out.println(text.trim().toLowerCase().replace("h", "x")); // => xexlet" hExLeT "является исходной строкой.trim()удаляет пробелы по краям и возвращает"hExLeT".toLowerCase()приводит к нижнему регистру и возвращает"hexlet".replace("h", "x")заменяет"h"на"x"и возвращает"xexlet".
Тот же результат получится без цепочки, через промежуточные переменные:
var text = " hExLeT ";
var step1 = text.trim(); // "hExLeT"
var step2 = step1.toLowerCase(); // "hexlet"
var step3 = step2.replace("h", "x"); // "xexlet"
System.out.println(step3);Каждый метод возвращает новую строку, и следующий метод применяется уже к ней.
" hExLeT ".trim().toLowerCase().replace("h", "x")
│ │ │
↓ ↓ ↓
"hExLeT" │ │
"hexlet" │
"xexlet"В цепочке вы просто двигаетесь слева направо, читая ее как обычное предложение. Если перепутать порядок, результат может отличаться. Например, замена пробелов сработает иначе, если выполнить ее до удаления концевых пробелов. В одних ситуациях итог совпадет случайно, в других порядок действительно повлияет на результат.
Где цепочка заканчивается
Цепочку можно продолжать, пока результат остается строкой или другим типом, у которого есть методы. Если метод возвращает число или другой примитивный тип, дальнейшие методы вызывать уже нельзя:
var text = "hexlet";
var index = text.toUpperCase().indexOf("E");
System.out.println(index); // => 1Метод indexOf() возвращает число 1, то есть позицию первого символа "E" в строке "HEXLET". У числа нет строковых методов, поэтому цепочка на этом заканчивается.
Цепочки методов служат удобным способом объединять несколько операций над значением без промежуточных переменных.
Задание
Напишите код, который берет данные из переменной name и выполняет капитализацию. В программировании так называют операцию, которая делает заглавной первую букву в слове, а все остальные переводит в нижний регистр. Например: heXlet => Hexlet. Программа должна выводить результат на экран.
Для извлечения частей слова, воспользуйтесь методом substring():
// 1 параметр – начальный индекс, 2 – конечный индекс (не включая)
"hexlet".substring(0, 1); // "h"
// По умолчанию до конца строки
"hexlet".substring(1); // "exlet"Java: Цепочки вызовов методов
Обработка данных может состоять из большого количества шагов, которые нужно выполнить один за другим.
Возьмем для примера такую задачу: сформировать адрес страницы в интернете на основе введенного пользователем названия статьи. Такая задача часто возникает при публикации статей в блогах. Подобные адреса выглядят так:
https://ru.hexlet.io/blog/posts/iz-vahtovika-v-programmirovanieПоследняя часть здесь iz-vahtovika-v-programmirovanie создана автоматически кодом, который мы написали на Хекслете. У нее есть специальное название — это слаг.
Какие шаги нужно выполнить, чтобы получить подобную строку? Вот лишь некоторые из них:
- Перевести все в нижний регистр, чтобы случайно не создавались дубли одинаковых страниц в поисковых системах
- Очистить название от пробельных символов по краям. Они могут случайно появиться при вводе
- Выполнить транслитерацию, потому что в адресах лучше использовать символы латинского алфавита
- Вырезать специальные символы вроде вопросительных и восклицательных знаков
- Заменить пробелы на дефисы
Часть шагов требует новых для нас знаний, поэтому мы их опустим. Остальные шаги будут выглядеть примерно так:
// Название, введенное пользователем. Для простоты на английском
var name = " How much is the fish? \n";
// вырезаем концевые пробелы и перенос строки
name = name.trim();
// Удаляем вопрос
name = name.replace("?", "");
// Заменяем пробелы на дефис
name = name.replace(" ", "-");
// Переводим в нижний регистр
name = name.toLowerCase();
System.out.println(name); // => how-much-is-the-fishЕсли внимательно посмотреть на этот код, то можно заметить общий шаблон. Метод возвращает данные, которые мы присваиваем переменной, и дальше по цепочке обрабатываем их.
Цепочка методов
Этот шаблон можно упростить, убрав промежуточное перезаписывание переменной. Метод возвращает новую строку, и к этой строке сразу применяется следующий метод. Такой прием называют цепочкой методов (method chaining).
var name = " How much is the fish? ";
name = name.trim().replace("?", "").replace(" ", "-").toLowerCase();
System.out.println(name); // => how-much-is-the-fishМетоды вызываются один за другим, как звенья в цепочке. Это позволяет писать компактный и читаемый код. Если цепочка становится слишком длинной, ее можно разбить на несколько строк:
name = name.trim()
.replace("?", "")
.replace(" ", "-")
.toLowerCase();Несмотря на удобство этого механизма, им не стоит злоупотреблять. Промежуточные переменные иногда упрощают понимание кода.
Порядок вычисления
В цепочке методов порядок выполнения идет слева направо. Каждый следующий метод вызывается на результате предыдущего:
var text = " hExLeT ";
System.out.println(text.trim().toLowerCase().replace("h", "x")); // => xexlet" hExLeT "является исходной строкой.trim()удаляет пробелы по краям и возвращает"hExLeT".toLowerCase()приводит к нижнему регистру и возвращает"hexlet".replace("h", "x")заменяет"h"на"x"и возвращает"xexlet".
Тот же результат получится без цепочки, через промежуточные переменные:
var text = " hExLeT ";
var step1 = text.trim(); // "hExLeT"
var step2 = step1.toLowerCase(); // "hexlet"
var step3 = step2.replace("h", "x"); // "xexlet"
System.out.println(step3);Каждый метод возвращает новую строку, и следующий метод применяется уже к ней.
" hExLeT ".trim().toLowerCase().replace("h", "x")
│ │ │
↓ ↓ ↓
"hExLeT" │ │
"hexlet" │
"xexlet"В цепочке вы просто двигаетесь слева направо, читая ее как обычное предложение. Если перепутать порядок, результат может отличаться. Например, замена пробелов сработает иначе, если выполнить ее до удаления концевых пробелов. В одних ситуациях итог совпадет случайно, в других порядок действительно повлияет на результат.
Где цепочка заканчивается
Цепочку можно продолжать, пока результат остается строкой или другим типом, у которого есть методы. Если метод возвращает число или другой примитивный тип, дальнейшие методы вызывать уже нельзя:
var text = "hexlet";
var index = text.toUpperCase().indexOf("E");
System.out.println(index); // => 1Метод indexOf() возвращает число 1, то есть позицию первого символа "E" в строке "HEXLET". У числа нет строковых методов, поэтому цепочка на этом заканчивается.
Цепочки методов служат удобным способом объединять несколько операций над значением без промежуточных переменных.
Задание
Напишите код, который берет данные из переменной name и выполняет капитализацию. В программировании так называют операцию, которая делает заглавной первую букву в слове, а все остальные переводит в нижний регистр. Например: heXlet => Hexlet. Программа должна выводить результат на экран.
Для извлечения частей слова, воспользуйтесь методом substring():
// 1 параметр – начальный индекс, 2 – конечный индекс (не включая)
"hexlet".substring(0, 1); // "h"
// По умолчанию до конца строки
"hexlet".substring(1); // "exlet"Ваше упражнение проверяется по этим тестам
import static org.assertj.core.api.Assertions.assertThat;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintStream;
class AppTest {
public static void main(String[] args) {
final var expected = "Hexlet";
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
App.main(null);
final var actual = out.toString().trim();
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
System.out.println(actual);
assertThat(actual).isEqualTo(expected);
}
}Решение учителя откроется через:
20:00
