Java 可选的map()和filter()操作的类型

Java 可选的map()和filter()操作的类型,java,java-stream,lazy-evaluation,eager,Java,Java Stream,Lazy Evaluation,Eager,的map()和filter()是否与流一样懒惰 我如何确认他们的类型 String r = Optional.of("abc") .map(s -> { System.out.println("Running map"); return s + "def"; }) .filter(s -> { System.out.

map()
filter()
是否与
流一样懒惰

我如何确认他们的类型

 String r = Optional.of("abc")
            .map(s -> {
                System.out.println("Running map");
                return s + "def";
            })
            .filter(s -> {
                System.out.println("First Filter");
                return s.equals("abcdef");
            })
            .map(s -> {
                System.out.println("mapping");
                return s + "jkl";
            })
            .orElse("done");

    System.out.println(r);
运行此操作将产生:

运行map,第一个过滤器,映射abcdefjkl

另一方面,运行以下命令:

String r = Optional.of("mnt") //changed
            .map(s -> {
                System.out.println("Running map");
                return s + "def";
            })
            .filter(s -> {
                System.out.println("First Filter");
                return s.equals("abcdef");
            })
            .map(s -> {
                System.out.println("mapping");
                return s + "jkl";
            })
            .orElse("done");
运行映射,第一个过滤器,完成

我一直认为,由于
映射
仅基于前面的
过滤器
执行,因此这将被视为
惰性
。事实证明这不是真的:

将执行来自
可选
映射
;而
中的一个不会

编辑


去投票给另一个答案。这是由于另一个原因而编辑的。

和可选
之间有根本区别

封装整个处理管道,在执行任何操作之前收集所有操作。这允许实现根据实际请求的结果选择不同的处理策略。这还允许在链中插入修饰符,如
unordered()
parallel()
,因为到目前为止,还没有做任何事情,所以我们可以改变后续实际处理的行为

一个极端的例子是
Stream.of(1,2,3).map(function).count()
,它在Java 9中根本不会处理
函数
,因为
3
的不变结果可以在没有任何限制的情况下确定

相反,
可选的
只是一个值的包装器(如果不是空的话)。将立即执行每个操作,以返回封装新值的新
可选
或空
可选
。在Java 8中,所有返回
可选
的方法,即
映射
平面映射
过滤器
,在应用于空可选时只返回一个空可选,因此当链接它们时,空可选成为一种死胡同


但是Java9将引入
可选或​(供应商您可以通过在映射或筛选表达式中记录某些内容,然后检查记录时间来轻松验证。一行代码会更有帮助:)不,最有帮助的是您自己找出答案,这样您可以学到最多。@MehrajMalik我的答案很糟糕(除此之外,它是完全错误的),请接受您拥有的另一个。三天没有异议…您所证明的是,空的
可选
不会评估映射函数。这不需要被认为是“溪流之路”。想象一下一个
哈希集
…删除所有元素后,处理所有元素的方法就变成了无操作。这并不能证明这些操作是急切的还是懒惰的。
可选
操作并不是懒惰的…@Holger我得到了一个提示,我错过了一些东西,谢谢回到这里。我一直认为,
filter.filter
在一个可选选项上会被认为是懒惰的,因为第二个过滤器不是根据第一个过滤器计算的。@Holger重新阅读了问题和答案。我是个白痴,谢谢你证明我错了。
 Optional.of("s").map(String::toUpperCase)
 Stream.of("test").map(String::toUpperCase)
Optional<String> first=Optional.of("abc");
Optional<String> second=first.map(s -> {
    System.out.println("Running map");
    return s + "def";
});
System.out.println("starting queries");
System.out.println("first: "+(first.isPresent()? "has value": "is empty"));
System.out.println("second: "+(second.isPresent()? "has value": "is empty"));
second.map("second's value: "::concat).ifPresent(System.out::println);
Stream<String> stream=Stream.of("abc").map(s -> {
    System.out.println("Running map");
    return s + "def";
});
System.out.println("starting query");
Optional<String> result = stream.findAny();
System.out.println("result "+(result.isPresent()? "has value": "is empty"));
result.map("result value: "::concat).ifPresent(System.out::println);