如何跳过 Stream<String> 的偶数行从 Files.lines 获得 [英] How to skip even lines of a Stream<String> obtained from the Files.lines

查看:16
本文介绍了如何跳过 Stream<String> 的偶数行从 Files.lines 获得的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这种情况下,只有奇数行具有有意义的数据,并且没有唯一标识这些行的字符.我的意图是获得与以下示例等效的内容:

In this case just odd lines have meaningful data and there is no character that uniquely identifies those lines. My intention is to get something equivalent to the following example:

Stream<DomainObject> res = Files.lines(src)
     .filter(line -> isOddLine())
     .map(line -> toDomainObject(line))

是否有任何干净"的方式来做到这一点,而不共享全局状态?

Is there any "clean" way to do it, without sharing global state?

推荐答案

一个干净的方法是深入一层并实现一个 Spliterator.在这个级别上,您可以控制对流元素的迭代,并在下游请求一个项目时简单地迭代两个项目:

A clean way is to go one level deeper and implement a Spliterator. On this level you can control the iteration over the stream elements and simply iterate over two items whenever the downstream requests one item:

public class OddLines<T> extends Spliterators.AbstractSpliterator<T>
    implements Consumer<T> {

    public static <T> Stream<T> oddLines(Stream<T> source) {
        return StreamSupport.stream(new OddLines(source.spliterator()), false);
    }
    private static long odd(long l) { return l==Long.MAX_VALUE? l: (l+1)/2; }
    Spliterator<T> originalLines;

    OddLines(Spliterator<T> source) {
        super(odd(source.estimateSize()), source.characteristics());
        originalLines=source;
    }

    @Override
    public boolean tryAdvance(Consumer<? super T> action) {
        if(originalLines==null || !originalLines.tryAdvance(action))
            return false;
        if(!originalLines.tryAdvance(this)) originalLines=null;
        return true;
    }

    @Override
    public void accept(T t) {}
}

那么你就可以像这样使用它了

Then you can use it like

Stream<DomainObject> res = OddLines.oddLines(Files.lines(src))
    .map(line -> toDomainObject(line));

此解决方案没有副作用,并保留了 Stream API 的大部分优点,例如惰性求值.但是,应该清楚的是,它对于无序流处理没有有用的语义(请注意在执行终端操作时使用 forEachOrdered 而不是 forEach所有元素)并且虽然原则上支持并行处理,但它不太可能非常有效......

This solution has no side effects and retains most advantages of the Stream API like the lazy evaluation. However, it should be clear that it hasn’t a useful semantics for unordered stream processing (beware about the subtle aspects like using forEachOrdered rather than forEach when performing a terminal action on all elements) and while supporting parallel processing in principle, it’s unlikely to be very efficient…

这篇关于如何跳过 Stream&lt;String&gt; 的偶数行从 Files.lines 获得的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆