Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sum a list of lists per column and per row using lambda functions in Java?

I have a list of lists like that:

List<List<Wrapper>> listOfLists = new ArrayList<>();

class Wrapper {
   private int value = 0;
   public int getValue() {
      return value;
   }
}

so it looks like that:

[
[Wrapper(3), Wrapper(4), Wrapper(5)],
[Wrapper(1), Wrapper(2), Wrapper(9)],
[Wrapper(4), Wrapper(10), Wrapper(11)],
]

Is there a concise way to flatten this list of lists like below using lambda functions in Java 8:

(per column): [Wrapper(8), Wrapper(16), Wrapper(25)]
(per row): [Wrapper(12), Wrapper(12), Wrapper(25)]

potentially it could work with different sizes of internal lists:

[
[Wrapper(3), Wrapper(5)],
[Wrapper(1), Wrapper(2), Wrapper(9)],
[Wrapper(4)],
]

this would result to:

(per column): [Wrapper(8), Wrapper(7), Wrapper(9)]
(per row): [Wrapper(8), Wrapper(11), Wrapper(4)]

it seems way more complicated than: Turn a List of Lists into a List Using Lambdas and 3 ways to flatten a list of lists. Is there a reason to prefer one of them?

and what I initially did is similar to although for lists: https://stackoverflow.com/a/36878011/986160

Thanks!

like image 438
Michail Michailidis Avatar asked Nov 08 '17 08:11

Michail Michailidis


People also ask

How do I print a list in Lambda?

// Create a list from a String array List list = new ArrayList(); String[] strArr = { "Chris", "Raju", "Jacky" }; for( int i = 0; i < strArr. length; i++ ) { list. add( strArr[i]); } // // Print the key and value of Map using Lambda expression // list. forEach((value) -> {System.

How do you make a list of lists in Java?

Given below is the simplest way to create a list of lists in Java: For String: List<List<String>> listOfLists = new ArrayList<>(); That's it.

How is a nested list defined in Java?

If you want nested lists you need to provide an appropriate generic parameter, e.g. List<List<List<String>>> .


1 Answers

Per row is actually pretty easy:

List<Wrapper> perRow = listOfLists.stream()
            .map(x -> x.stream().mapToInt(Wrapper::getValue).sum())
            .map(Wrapper::new)
            .collect(Collectors.toList());

Per column on the other hand is not that trivial:

private static List<Wrapper> perColumn(List<List<Wrapper>> listOfList) {
    int depth = listOfList.size();
    int max = listOfList.stream().map(List::size).max(Comparator.naturalOrder()).get();
    return IntStream.range(0, max)
            .map(x -> IntStream.range(0, depth)
                    .map(y -> listOfList.get(y).size() < y ? 0 : listOfList.get(y).get(x).getValue())
                    .sum())
            .mapToObj(Wrapper::new)
            .collect(Collectors.toList());
}
like image 94
Eugene Avatar answered Nov 15 '22 09:11

Eugene