首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8 Stream每个索引运行一个函数,而另一个函数每n次运行一次

Java 8 Stream每个索引运行一个函数,而另一个函数每n次运行一次
EN

Stack Overflow用户
提问于 2017-07-22 06:12:17
回答 4查看 489关注 0票数 1

迭代Java8 Stream的最好方法是什么,这样我就可以为每个元素(forEach)执行一个函数,而对每10个元素执行另一个函数。使用foreach的每个元素如下所示。我可以使用什么函数.to截取第n个元素并执行第二个函数调用?

示例代码如下:

代码语言:javascript
复制
Stream<String> strings = Files.lines(path); //some stream

stream.forEach(s -> System::println)// every element but how can i perform 
EN

回答 4

Stack Overflow用户

发布于 2017-07-22 13:39:07

由于使用了Guava version 22,您可以使用Streams.forEachPair来完成您想要的操作:

代码语言:javascript
复制
Stream<String> strings = Stream.of("a", "b", "c", "d", "e", "f");

Stream<Long> indexes = Stream.iterate(0L, i -> i + 1L);

Streams.forEachPair(strings, indexes, (s, i) -> {
    if (i % 3 == 0) {
        System.out.println("Every 3rd element: " + s);
    } else {
        System.out.println(s);
    }
});

这将创建一个从0L开始的连续Long元素的无限流,并在内部用strings流压缩该流。Streams.forEachPair接受一个BiConsumer,它接收每对元素,每个流一个元素,并根据索引是否是第三个元素来执行操作。

您可以使用以下助手方法对其进行更多抽象:

代码语言:javascript
复制
static <T> void forEachNthOrElse(
    Stream<T> stream, 
    int n, 
    Consumer<T> onNthElement,
    Consumer<T> onAnyOther) {

    Streams.forEachPair(
        stream, 
        Stream.iterate(0L, i -> i + 1),
        (t, i) -> {
            Consumer<T> action = i % n == 0 ? onNthElement : onAnyOther;
            action.accept(t);
        });
}

对于相同的示例,您可以使用它,如下所示:

代码语言:javascript
复制
forEachNthOrElse(
    strings, 
    3, 
    s -> System.out.println("Every 3rd element: " + s), 
    System.out::println);

注意:我不确定是否需要始终执行System.out::println操作,或者只在元素不是第n个元素时执行。我实现了BiConsumer来执行一个或另一个操作。如果情况并非如此(即,如果您希望对第n个元素执行一个操作,并始终执行另一个操作,即使是对第n个元素),则应该相应地更改代码。

票数 5
EN

Stack Overflow用户

发布于 2017-07-24 13:49:00

通过使用提供的zipWithIndex方法,使用Vavr(Javaslang)可以相当简单:

代码语言:javascript
复制
 stream
    .zipWithIndex()
    .forEach(t2 -> {
        // something that runs for each element
        if (t2._2 % 10 == 0) {
            // something that runs every 10 elements
        }
    });
票数 2
EN

Stack Overflow用户

发布于 2017-07-22 06:19:46

由于流不支持chunk/split特性,但我已经回答了其他问题,所以我将其粘贴在这里。我希望它能帮助你,例如:

代码语言:javascript
复制
Stream<String> strings = Files.lines(path); //some stream

//                  v--- skip the last chunk if the chunk size < 10?
split(strings, 10 , true).forEach((List<String> chunk)->{
//         each chunk size is 10 ---^ 

    //                        v--- Every element using foreach displayed  
    chunk.forEach(System.out::println);

    //                 v--- another for every 10 element.
    System.out.println(chunk);

});

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.stream.Stream;    
import static java.util.stream.StreamSupport.stream;


<T> Stream<List<T>> split(Stream<T> source,
                          int limit, boolean skipRemainingElements) {

    //variables just for printing purpose
    Spliterator<T> it = source.spliterator();
    long size = it.estimateSize();
    int c = it.characteristics();// characteristics

    return stream(new AbstractSpliterator<List<T>>(size, c) {
        private int thresholds = skipRemainingElements ? limit : 1;

        @Override
        @SuppressWarnings("StatementWithEmptyBody")
        public boolean tryAdvance(Consumer<? super List<T>> action) {
            List<T> each = new ArrayList<>(limit);

            while (each.size() < limit && it.tryAdvance(each::add)) ;

            if (each.size() < thresholds) return false;

            action.accept(each);
            return true;
        }

    }, false).onClose(source::close);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45247430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档