首页 > 解决方案 > 将流中的 2 个对象映射到单个第三个对象?

问题描述

如果我有要转换的对象的时间戳列表和文件路径,我可以制作一组期望方法签名的转换器Converter(filePath, start, end)吗?

更多细节(伪代码):

一些有时间戳的列表(想象一下它们以秒为单位)path = somewhere,,,list = {0, 15, 15, 30}

我怎么能做这样的事情:list.stream。魔术.map(start, end -> new Converter (path, start, end))?

结果new Converter (path, 0, 15), new Converter(path, 15, 30)

注意:我知道BiFunction,但据我所知,流没有实现它。

标签: javacollectionsjava-stream

解决方案


有许多方法可以使用流获得所需的结果。

但首先,您不必使用 Stream API,如果要处理包含数十个和数百个元素的列表,我建议您使用普通的旧列表迭代。

例如尝试下面的代码示例。

我们很容易看到由流的性质引起的两个表面问题以及它们与将其元素配对的想法的不相容性:

  • 有必要应用有状态的函数,这在使用中真的很棘手,map()应该被认为是脏编码;并且映射会在应该正确过滤掉的偶数地方产生一些空值;
  • 当流包含奇数个元素时就会出现问题,而您永远无法预测它是否存在。

如果您决定使用流,那么为了清楚地说明我们需要 Iterator、Spliterator 或 Collector 的自定义实现 - 取决于需求。无论如何,有几个不明显的极端情况你不会乐意自己实现,所以可以尝试大量的第三方流库。最流行的两个是StreamexRxJava。他们肯定有配对流元素的工具......但不要忘记检查您的案例的性能!

import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;

public class Sample
{
    public static void main(String... arg)
    {        
        String path = "somewhere";

        Stream<Converter> stream = Stream.of(0, 15, 25, 30).map(
            new Function<Integer, Converter>()
            {
                int previous;
                boolean even = true;

                @Override
                public Converter apply(Integer current)
                {
                    Converter converter = even ? null : new Converter(path, previous, current);

                    even = !even;

                    previous = current;

                    return converter;
                }
            }).filter(Objects::nonNull);

        stream.forEach(System.out::println);
    }

    static class Converter
    {
        private final String path;
        private final int start;
        private final int end;

        Converter(String path, int start, int end)
        {

            this.path = path;
            this.start = start;
            this.end = end;
        }

        public String toString()
        {
            return String.format("Converter[%s,%s,%s]", path, start, end);
        }
    }
}

推荐阅读