Java Streams - 如何在每第n个项目中执行中间函数 [英] Java Streams — How to perform an intermediate function every nth item
问题描述
我正在寻找一个Stream上的操作,使我能够每隔n项执行一次非终端(和/或终端)操作。虽然我使用素数流,例如,流可以很容易地生成网络请求,用户操作或其他一些冷数据或实时Feed。
由此:
持续时间start = Duration.ofNanos(System.nanoTime());
IntStream.iterate(2,n - > n + 1)
.filter(Findprimes :: isPrime)
.limit(1_000_1000 * 10)
。的forEach(的System.out ::的println);
System.out.println(持续时间:+ Duration.ofNanos(System.nanoTime())。minus(start));
对于这样的流函数:
IntStream.iterate(2,n - > n + 1)
.filter(Findprimes :: isPrime)
.limit(1_000_1000 * 10)
.peekEvery(10,System.out :: println)
.forEach(it - > {});
创建一个帮助方法来包装 peek()
consumer:
public static IntConsumer every(int count,IntConsumer consumer){
if(count< = 0)
抛出新的IllegalArgumentException(Count必须> 1:Got+ count);
返回新的IntConsumer(){
private int i;
@Override
public void accept(int value){
if(++ this.i == count){
consumer.accept(value);
this.i = 0;
}
}
};
}
您现在几乎可以按照自己的意愿使用它:
IntStream.rangeClosed(1,20)
.peek(every(5,System.out :: println))
。计数();
输出
< pre class =lang-none prettyprint-override>
5
10
15
20
辅助方法可以放在实用程序类中并静态导入,类似于 收集器
类只是静态辅助方法。
如@ user140547所述 comment ,此代码不是线程安全的,因此不能与并行流一起使用。此外,输出顺序会混乱,所以无论如何将它与并行流一起使用并没有多大意义。
I am looking for an operation on a Stream that enables me to perform a non-terminal (and/or terminal) operation every nth item. Although I use a stream of primes for example, the stream could just as easily be web-requests, user actions, or some other cold data or live feed being produced.
From this:
Duration start = Duration.ofNanos(System.nanoTime());
IntStream.iterate(2, n -> n + 1)
.filter(Findprimes::isPrime)
.limit(1_000_1000 * 10)
.forEach(System.out::println);
System.out.println("Duration: " + Duration.ofNanos(System.nanoTime()).minus(start));
To a stream function like this:
IntStream.iterate(2, n -> n + 1)
.filter(Findprimes::isPrime)
.limit(1_000_1000 * 10)
.peekEvery(10, System.out::println)
.forEach( it -> {});
Create a helper method to wrap the peek()
consumer:
public static IntConsumer every(int count, IntConsumer consumer) {
if (count <= 0)
throw new IllegalArgumentException("Count must be >1: Got " + count);
return new IntConsumer() {
private int i;
@Override
public void accept(int value) {
if (++this.i == count) {
consumer.accept(value);
this.i = 0;
}
}
};
}
You can now use it almost exactly like you wanted:
IntStream.rangeClosed(1, 20)
.peek(every(5, System.out::println))
.count();
Output
5
10
15
20
The helper method can be put in a utility class and statically imported, similar to how the Collectors
class is nothing but static helper methods.
As noted by @user140547 in a comment, this code is not thread-safe, so it cannot be used with parallel streams. Besides, the output order would be messed up, so it doesn't really make sense to use it with parallel streams anyway.
这篇关于Java Streams - 如何在每第n个项目中执行中间函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!