收集可选项

时间:2016-09-18 23:29:11

标签: java java-8 guava collect

鉴于Guava Immutable表,我需要处理所有单元格,并根据返回Java Optional的一些mapper结果筛选出一些单元格,

  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 - &gt; cell.get())”并通过累加器本身收集cell.get()?

2 个答案:

答案 0 :(得分:3)

除了使用方法参考:

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)
        );
}

For more details see this answer

答案 1 :(得分: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不同序列