gpt4 book ai didi

java - 等价于 Scala dropWhile

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:04:01 24 4
gpt4 key购买 nike

我正在努力寻找一种方法来根据谓词跳过流开头的某些元素。

像这样:

dropWhile( n -> n < 3, Stream.of( 0, 1, 2, 3, 0, 1, 2, 3, 4 ) )
.forEach( System.out::println );
3   
0
1
2
3
4

这相当于 Scala dropWhile

最佳答案

这种操作不是 Stream 的预期用例,因为它包含元素之间的依赖性。因此,该解决方案可能看起来并不优雅,因为您必须为谓词引入一个全状态变量:

class MutableBoolean { boolean b; }
MutableBoolean inTail = new MutableBoolean();

IntStream.of(0, 1, 2, 3, 0, 1, 2, 3, 4)
.filter(i -> inTail.b || i >= 3 && (inTail.b = true))
.forEach(System.out::println);

请注意,与您的示例相比,条件必须相反。

当然,您可以在方法中隐藏讨厌的细节:

public static void main(String... arg) {
dropWhile(n -> n < 3, Stream.of(0, 1, 2, 3, 0, 1, 2, 3, 4))
.forEach(System.out::println);
}
static <T> Stream<T> dropWhile(Predicate<T> p, Stream<T> s) {
class MutableBoolean { boolean b; }
MutableBoolean inTail = new MutableBoolean();
return s.filter(i -> inTail.b || !p.test(i) && (inTail.b = true));
}

一种更复杂但更简洁且可能更有效的方法是深入研究金属,即 Spliterator 接口(interface):

static <T> Stream<T> dropWhile(Predicate<T> p, Stream<T> s) {
Spliterator<T> sp = s.spliterator();
return StreamSupport.stream(new Spliterators.AbstractSpliterator<T>(
sp.estimateSize(), sp.characteristics() & ~Spliterator.SIZED) {
boolean dropped;
public boolean tryAdvance(Consumer<? super T> action) {
if(dropped) return sp.tryAdvance(action);
do {} while(!dropped && sp.tryAdvance(t -> {
if(!p.test(t)) {
dropped=true;
action.accept(t);
}
}));
return dropped;
}
public void forEachRemaining(Consumer<? super T> action) {
while(!dropped) if(!tryAdvance(action)) return;
sp.forEachRemaining(action);
}
}, s.isParallel());
}

此方法的使用方式与第一个 dropWhile 方法相同,但它甚至可以用于并行流,尽管效率不如您希望的那样。

关于java - 等价于 Scala dropWhile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25569836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com