Вот для чего flatMap
.
Если у вас есть коллекция Path
экземпляров в path
, вы можете использовать
paths.stream()
.flatMap(path -> {
try { return Files.find(path, Integer.MAX_VALUE,
(p, attrs) -> attrs.isRegularFile() && p.toString().endsWith(".json")); }
catch (IOException ex) { throw new UncheckedIOException(ex); }
})
.forEach(System.out::println);
Это немного неуклюже из-зак тому, что мы имеем дело с проверенным IOException
, заявленным find
здесь.Возврат его в UncheckedIOException
является самым простым выбором, поскольку именно так поступит поток, возвращаемый find
, если возникнет проблема ввода-вывода при обработке потока.Сравните с документацию find
Если при обращении к каталогу после возврата из этого метода выбрасывается IOException
, он переносится вUncheckedIOException
, который будет выброшен из метода, вызвавшего доступ.
Таким образом, выполнение того же в нашей функции упрощает обработку ошибок вызывающей стороны, так как она простодолжен обрабатывать UncheckedIOException
с.
Здесь нет способа использовать try(…)
, но именно поэтому flatMap
снимет с нас это бремя.Как его документация гласит:
Каждый сопоставленный поток закрыт после помещения его содержимого в этот поток.
Итак, как только наша функция вернула подпоток, mplementation Stream сделает для нас правильную вещь.
Вы можете объединить произвольные операции потока вместо .forEach(System.out::println);
для обработки всех элементов сплющенного потока, напримеродин поток.
Если ваша входная коллекция содержит экземпляры String
вместо Path
, вы можете просто добавить paths.stream().map(Paths::get)
вместо paths.stream()
к операции flatMap
.