Java 8: vertically slicing an array of lists

I am learning Java 8 lambdas and threads. So, I have a list of lists having different lengths. Lists contain integers.

What is the best way to collect vertical slices in another list of lists, i.e. collect all integers with index 0 from all source lists in slice 0, index 1 in slice 1 and so on to the length of the longest list (filling zeros for shorter lists)

I know that it is trivial to pass code to a few traditional loops for this, but how to do it using Java 8 functions?

+4
source share
2 answers

This is a pretty interesting question - thanks for posting. I am sure you will see some interesting answers. Here is my attempt:

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())
+4

, 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.*;, .

+1

Source: https://habr.com/ru/post/1570438/


All Articles