【问题标题】:Java 8 collect() only isPresent() Optional values [duplicate]Java 8 collect() only isPresent() 可选值 [重复]
【发布时间】:2017-02-16 15:32:52
【问题描述】:

在 Java 8 中是否有更优雅的方法可以实现这一点?

list.stream()
    .map(e -> myclass.returnsOptional(e))
    .filter(Optional::isPresent)
    .map(Optional::get)
    .collect(Collectors.toList());

我说的是filter(Optional::isPresent),然后是map(Optional::get),我想优雅地在列表中收集只有Optional 有价值的结果。

【问题讨论】:

  • 对我来说看起来不错。我不确定你不喜欢它的什么。
  • 如果您所有的 Optional 都有结果,那么这不再是 Optional 了……而不是返回一个 optional 并检查 isPresent 是否可以返回空值和过滤器,它会缩短一步。 list.stream().map(e -> myclass.returnsObjectOrNull(e)).filter(Objects::nonNull).collect(Collectors.toList())
  • .map(o -> o.map(Stream::of).orElseGet(Stream::empty)) 或在此处查看答案:stackoverflow.com/questions/22725537/…
  • 我知道在 java9 中可选的有一个流,所以不是filtermap,你可以做flatMap(Optional::stream) 所以如果没有人有答案,请记住java9
  • 看起来不错(我已经使用过这个)。轻微的优雅改进:.map(myclass::returnsOptional) 而不是 lambda

标签: java java-8 java-stream optional


【解决方案1】:

在您的情况下,您可以使用一个flatMap 而不是map filtermap 的组合。 为此,最好定义一个单独的函数来创建流:public private static Stream<Integer> createStream(String e),以便在 lambda 表达式中没有几行代码。

请查看我的完整演示示例:

 public class Demo{
    public static void main(String[] args) {
        List<String> list = Arrays.asList("1", "2", "Hi Stack!", "not", "5");
        List<Integer> newList = list.stream()
                .flatMap(Demo::createStream)
                .collect(Collectors.toList());
        System.out.println(newList);
    }

    public static Stream<Integer> createStream(String e) {
        Optional<Integer> opt = MyClass.returnsOptional(e);
        return opt.isPresent() ? Stream.of(opt.get()) : Stream.empty();
    }
}


class MyClass {
    public static Optional<Integer> returnsOptional(String e) {
        try {
            return Optional.of(Integer.valueOf(e));
        } catch (NumberFormatException ex) {
            return Optional.empty();
        }
    }
}

如果 returnOptional 不能是静态的,您将需要使用“箭头”表达式而不是“方法引用”

【讨论】:

    【解决方案2】:

    不确定它是否如此不同,但您可以根据您的可选项进行过滤,而不是获取可选项并接下来进行过滤。 像这样?

    list.stream()
        .filter(e -> myclass.returnsOptional(e).isPresent())
        .collect(Collectors.toList());
    

    注意:这仅在 returnOptional 返回与原始列表项类型相同的对象类型时才有效。

    【讨论】:

    • 这不会产生与 OP 产生的列表相同的列表。
    • 嗯,为什么不呢?
    • 因为list 的类型是Foo,而myclass.returnsOptional(Foo) 返回Optional&lt;Bar&gt;。最后我需要List&lt;Bar&gt; 而你正在生产List&lt;Foo&gt;
    • 我明白了。我没有意识到您的 Optional 返回与原始问题不同的类型。谢谢你的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    相关资源
    最近更新 更多