收集可选项目

Collect optional items

给定 Guava Immutable table,我需要处理所有单元格,并根据 returns Java 可选的映射器结果过滤掉一些单元格,

  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()?

除了使用方法参考:

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.

您可以将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序列。