JavaRush /Курси /Java Syntax Zero /Робота з потоками, частина 2

Робота з потоками, частина 2

Java Syntax Zero
Рівень 19 , Лекція 5
Відкрита

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://yahoo.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-винятки. І тричі, перш ніж використовувати їх у конструкторі.


Коментарі (5)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Aleksey Golovin Рівень 55
7 листопада 2025
Ось так можно обійти checked виняток

public class TestURI {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("https://google.com");
        list.add("https://linkedin.com");
        list.add("https://yahoo.com");
        Stream<URI> stream1 = list.stream().map( TestURI::safeURI );
    }

    private static URI safeURI(String link) {
        try {
            return new URI(link);
        }
        catch (URISyntaxException e) {
            return null;
        }
    }
}
Sava_crosava Рівень 23
3 листопада 2023
А мені це все починає подобатись, надіюсь далі не буде завалу)
WhoAMI Рівень 51
29 грудня 2022
друга задачка здивувала своєю простотою
Grimnir Рівень 34
22 січня 2023
Та всі крайні задачі якісь прості, але все одно лишається враження, що от зробив, але не все зрозуміло, як працює
Павло Лєбєдєв Рівень 111 Expert
9 серпня 2023
Мені, на щастя, зрозуміло. Якщо залишилось щось незрозумілим - перечитайте ще раз та/або запитайте в ментора.