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

Мы создали коллекцию, записали в нее 3 ссылки на сайты в интернете. Затем получили у коллекции объект 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-исключения. И трижды, прежде чем использовать их в конструкторе.