将流中的2个对象映射到单个第3个对象?

时间:2018-05-19 02:00:27

标签: java collections java-stream

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

更多细节(Pseuo-Code):

一些包含时间戳的列表(想象一下,它们是在几秒钟内)path = somewherelist = {0, 15, 15, 30}

我该怎么做这样的事情: list.stream。 magic .map(开始,结束 - >新转换器(路径,开始,结束))?

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

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

1 个答案:

答案 0 :(得分:1)

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

但首先,你没有义务使用 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);
        }
    }
}