Собирать дополнительные предметы
Учитывая таблицу Guava Immutable, мне нужно обработать все ячейки и отфильтровать некоторые ячейки на основе некоторого результата сопоставления, который возвращает Java Optional,
immutbleTable.cellSet()
.parallelStream()
.map(cell -> processAndGetOptionalResult(cell))
.filter(cell -> cell.isPresent())
.map(cell -> cell.get())
.collect(Collector.of(
ImmutableTable.Builder::new,
ImmutableTable.Builder::put,
(l, r) -> l.putAll(r.build()),
ImmutableTable.Builder<String,String,String>::build)
);
}
Есть ли лучший способ добиться этого? Есть ли способ, которым я могу удалить "map(cell -> cell.get())" и собрать cell.get () через сам аккумулятор?
2 ответа
Вы можете интегрировать обработку Optional
в Collector
:
resultTable = immutableTable.cellSet().parallelStream()
.map(cell -> processAndGetOptionalResult(cell))
.collect(Collector.of(
ImmutableTable.Builder::new,
(b,o) -> o.ifPresent(b::put),
(l, r) -> l.putAll(r.build()),
ImmutableTable.Builder<String,String,String>::build)
);
Это работает гладко, так как функция-накопитель представляет действие, и выполнение действия (если оно не пустое) является одним из канонических вариантов использования для Optional
, в отличие от isPresent
-get
последовательность.
Помимо использования ссылок на методы:
immutbleTable.cellSet()
.parallelStream()
.map(this::processAndGetOptionalResult)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collector.of(
ImmutableTable.Builder::new,
ImmutableTable.Builder::put,
(l, r) -> l.putAll(r.build()),
ImmutableTable.Builder<String,String,String>::build)
);
}
Ответ - нет - в текущем (JDK 8) API нет лучшего способа добиться этого. В JDK 9 Optional
буду иметь .stream()
метод, который позволит использовать одну операцию - flatMap
:
immutbleTable.cellSet()
.parallelStream()
.map(this::processAndGetOptionalResult)
.flatMap(Optional::stream)
.collect(Collector.of(
ImmutableTable.Builder::new,
ImmutableTable.Builder::put,
(l, r) -> l.putAll(r.build()),
ImmutableTable.Builder<String,String,String>::build)
);
}