Java - transposing a list of list using streams
Asked Answered
B

1

6

For improvement purposes, I am trying to use exclusively streams to transpose a list of list.

By that I mean, that I have a List of List of Doubles that contains for example

1 2 3 4
5 6 7 8

And I would like to obtain a List of List of Doubles that contains

1 5
2 6
3 7
4 8

An iterative way is provided in the following Stack Overflow question : How to transpose List<List>?

I have only thought of ugly solutions so far, such as replacing the Double with a custom object that holds the value and the index in the list, flatten using flatMap, build it again using groupBy with the index I saved and then go back to Doubles.

Please let me know if you are aware of any clean way. Thanks.

Buchenwald answered 20/3, 2018 at 15:28 Comment(0)
M
8

I like your question! Here's a simple way to achieve it, as long as the Lists are square (every List contains the same number of elements):

List<List<Integer>> list = List.of(List.of(1, 2, 3, 4), List.of(5, 6, 7, 8));

IntStream.range(0, list.get(0).size())
         .mapToObj(i -> list.stream().map(l -> l.get(i)).collect(Collectors.toList()))
         .collect(Collectors.toList());

The above code returns the following:

[[1, 5], [2, 6], [3, 7], [4, 8]]

Note: This will not perform well for large lists.

Mechling answered 20/3, 2018 at 16:18 Comment(2)
Thanks. Could you please tell me why is the performance bad for long lists ? I take it there the complexity order heightens - is it caused by the .stream() being O(depth 2 list length) and thus inducing a O(depth 2 list length²) term ? If I'm using ArrayList s, the .map(l -> l.get(i)) call should be O(depth 2 list length), right ?Buchenwald
Well this method creates a Stream for each element of one of the Lists in list. It's equivalent to a nested for-loop and its time complexity is O(n * m). There exist many algorithms to transpose matrices that will perform better than this, especially with the added stream overhead.Mechling

© 2022 - 2024 — McMap. All rights reserved.