Java 8:垂直切片列表数组

时间:2015-01-08 09:53:32

标签: java java-8

我正在学习Java 8 lambdas和stream。 所以,我得到了一系列不同长度的列表。列表包含整数。

在另一个列表列表中收集垂直切片的最佳方法是什么,即从切片0中的所有原始列表,切片1中的索引1收集索引为0的所有整数,直到最长列表的长度为止(填充)缩短列表的零)

我知道为此手工编写几个传统循环是微不足道的,但是使用Java 8功能呢?

2 个答案:

答案 0 :(得分:4)

这是一个非常有趣的问题 - 感谢发布。我相信你会看到一些有趣的答案。这是我的尝试:

List<Integer> source[];
List<List<Integer>> slices = IntStream.range(0, Arrays.stream(source).mapToInt(List::size).max().getAsInt())
     .mapToObj(index -> Arrays.stream(source).map(list -> list.size() > index ? list.get(index) : 0)
         .collect(Collectors.toList()))
     .collect(Collectors.toList())

答案 1 :(得分:2)

这是一个解决方案,它不会为较短的List s插入填充值:

List<List<Integer>> slices = Stream.of(source).flatMap(l->
    IntStream.range(0, l.size()).mapToObj(i->new int[]{i, l.get(i)})
).collect(collectingAndThen(
    groupingBy(a->a[0], TreeMap::new, mapping(a->a[1], toList())),
    m->new ArrayList<>(m.values()))
);

这可以扩展为零填充版本,如下所示:

int maxSize=IntStream.range(0,source.length).map(i->source[i].size()).max().orElse(0);
List<List<Integer>> slices = Stream.of(source).flatMap(l->
    Stream.concat(
      IntStream.range(0, l.size()).mapToObj(i->new int[]{i, l.get(i)}),
      IntStream.range(l.size(), maxSize).mapToObj(i->new int[]{i, 0})
    )
).collect(collectingAndThen(
    groupingBy(a->a[0], TreeMap::new, mapping(a->a[1], toList())),
    m->new ArrayList<>(m.values()))
);

两种解决方案都假设您执行import static java.util.stream.Collectors.*;,否则代码变得非常难以理解。