Stream take,同时在同一管道中进行排序的流

问题描述 投票:2回答:1

我正在尝试使用java9的takeWhile筛选已排序的流,以从流的开头获取与字段共享相同值的对象。我无法写出正确的谓词。这可以通过中断流水线的两个步骤来完成。

Stream.of(objA, objB, objC, objD, objE, objF, objG)
    .takeWhile(" get the value of objA´s field and take 
   as long as as other objects value for that field is the same as objA´s");

分两步,我可以做类似的事情

int x = Stream.of(objA, objB, objC, objD, objE, objF, objG).findFirst().get().getSomeValue();

Stream.of(objA, objB, objC, objD, objE, objF, objG).takeWhile(e -> e.getSomeValue() == x);

一个简化的例子可能是

Stream.of(5,5,5,5,13,14,5,5,2,5,5,6)
.takeWhile(get the first four '5'´s)

可以在没有中间步骤的情况下使用optional.get完成此操作吗?

java stream java-9
1个回答
0
投票

(笨拙的)解决方法是使用包含effectively final或第一个值的可变持有人对象(因为引用必须为null)。在此示例中,我们将使用AtomicReference

AtomicReference<MyClass> holder = new AtomicReference<>();

sortedStream.takeWhile(e -> holder.get() == null || holder.get().equals(e))
.map(e -> { holder.set(e); return e; })
.collect(Collectors.toList());  // Or whatever further processing you need

现在这仍然包含一个额外的步骤,但是由于Stream只能被处理一次,因此findFirst()方法将永远无法工作。即使设置了holder对象,这也将继续设置它,但这只是一个小麻烦而不是问题。

如果您确实使用这种方法,建议您添加指向该问题/答案的注释,或者至少以某种方式尝试解释此代码的实现,因为它并不立即显而易见。

© www.soinside.com 2019 - 2024. All rights reserved.