Stream takeWhile 用于同一管道中的排序流
Stream takeWhile for a sorted stream in the same pipeline
我正在尝试使用 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 的中间步骤来完成吗?
一个(有点笨拙的)解决方法是使用一个可变的 holder 对象(因为引用必须是 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());
现在这仍然包含一个额外的步骤,但是由于 Stream
只能处理一次,所以 findFirst()
方法无论如何都行不通。这也会继续设置 holder 对象,即使它已被设置,但这只是一个小麻烦而不是问题。
正如 Holger 所指出的,更好、更精简的版本是
sortedStream.takeWhile(e -> holder.compareAndSet(null, e.getSomeValue()) || e.getSomeValue() == holder.get())
.collect(Collectors.toList());
其中第一个元素 compareAndSet
赋值,返回 true,随后的元素与持有者的值进行比较。
如果您确实使用这种方法,我建议添加指向此 question/answer 的注释,或者至少尝试以某种方式解释这段代码的实现,因为阅读代码的人可能不会立即明白这一点.
我正在尝试使用 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 的中间步骤来完成吗?
一个(有点笨拙的)解决方法是使用一个可变的 holder 对象(因为引用必须是 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());
现在这仍然包含一个额外的步骤,但是由于 Stream
只能处理一次,所以 findFirst()
方法无论如何都行不通。这也会继续设置 holder 对象,即使它已被设置,但这只是一个小麻烦而不是问题。
正如 Holger 所指出的,更好、更精简的版本是
sortedStream.takeWhile(e -> holder.compareAndSet(null, e.getSomeValue()) || e.getSomeValue() == holder.get())
.collect(Collectors.toList());
其中第一个元素 compareAndSet
赋值,返回 true,随后的元素与持有者的值进行比较。
如果您确实使用这种方法,我建议添加指向此 question/answer 的注释,或者至少尝试以某种方式解释这段代码的实现,因为阅读代码的人可能不会立即明白这一点.