【发布时间】:2021-04-21 14:08:40
【问题描述】:
我一直在玩流,然后我注意到当我执行以下操作时,它不会在控制台中产生输出:
String[] is = {"Hello", "World", "My", "Name", "Is", "Jacky"};
Arrays.stream(is).peek(s -> System.out.println(s));
我认为这是因为peek() 是一种非终止流方法,应该使用forEach() 而不是peek() 来终止流并产生结果:
Arrays.stream(is).forEach(s -> System.out.println(s));
但是,有没有一种方法可以“提前”终止流,可能使用自定义终止方法(功能接口),除了终止流之外什么都不做?.. 有没有合适的方法来做到这一点是否已经存在于 Java 中?
我知道我可以这样做:
Arrays.stream(is).peek(s -> System.out.println(s)).forEach(s -> {});
但这感觉很浪费。
【问题讨论】:
-
@DanielZ。我猜 OP 的问题是是否有无操作终止语句。我对 Java 1.8 以外的知识非常有限。至少对于 Java 1.8,答案似乎是“否”:没有
sink()/consume()/terminate()操作。写一个显然是微不足道的(正如 OP 所示);但什么是“最不浪费”的方式(forEach(s -> {})实际上似乎是一个不错的选择)? -
@KonradRudolph 没有这样的事情。对 OP 来说更糟糕的是,理论上,
forEach(s -> {})可以被编译器完全解除(它毕竟什么都不做),因此任何其他中间操作也是如此,有效地使这个流成为 NO-OP。 -
从角度来看,如果您发现自己处于需要无操作终端操作的位置,那么根据 java,您不需要以流开头...
-
你不能在
forEach之后使用collect -
原则上,如果
forEach被一个可证明忽略其输入的函数调用,即使该函数确实做了一些事情,也可以允许实现不消耗流的元素,例如x -> System.out.println("Hello")。理论上,这可以通过使用null输入调用函数.count()次来实现,并且将难以编写正式保证消费流的 any 无操作终端操作。跨度>
标签: java java-stream