1. Перетворення даних

А ще клас Stream<T> має метод, який дає змогу перетворити дані з одного типу на інший. Цей метод називається map().

Він теж повертає потік Stream<R>, але вже з елементами нового типу. Як параметр у метод map() потрібно передати функцію, що перетворює один тип даних на інший.

Приклади:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stream2 = stream.map((x) -> String.valueOf(x));
Перетворюємо потік Integer на потік String

Функція, що її передали в метод map() як параметр, отримує число x, а як результат повертає рядок. Можна, до речі, цей код скоротити:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stream2 = stream.map(String::valueOf);
Перетворюємо потік Integer на потік String

Перетворення рядка на число

Так само можна написати код і для перетворення рядка на число — теж нічого складного:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stream2 = stream.map(String::valueOf);
Stream<Integer> stream3 = stream2.map(Integer::parseInt);
Перетворюємо потік String на потік Integer

Перетворення рядка на URI

Операції з перетворення даних можуть бути великими й важкими. Припустімо, ми хочемо перетворити колекцію рядків на об'єкти URI. Це дуже легко зробити, адже URI отримує рядок як параметр конструктора.

ArrayList<String> list = new ArrayList<String>();
list.add("https://google.com");
list.add("https://linkedin.com");
list.add("https://yandex.com");

Stream<URI> stream = list.stream().map( URI::new );
Перетворюємо потік String на потік URI

Ми створили колекцію, записали в неї три посилання на сайти в інтернеті. Потім отримали з колекції об'єкт Stream<String>, а з нього — об'єкт Stream<URI>. А в метод map передали посилання на метод, який буде використовуватися для перетворення зі String на URI.

Цей метод (конструктор) має отримувати як параметр тип String. Усе начебто ідеально…


2. Винятки

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

Колись давно їм спала на думку чудова ідея — додати в конструктор (!) класу URI checked-виняток URISyntaxException. А такі винятки потрібно обов'язково обгортати конструкцією try-catch.

Тому останній рядок нашого коду матиме такий вигляд:

Stream<URI> stream = list.stream().map(str ->
{
  try
  {
     return new URI(str);
  }
  catch (URISyntaxException e)
  {
     e.printStackTrace();
     return null;
  }
});

Що вам сказати? Треба двічі подумати, перш ніж використовувати checked-винятки. І тричі, перш ніж використовувати їх у конструкторі.