Home > database >  How to make a new List of ArrayList from a List of ArrayList?
How to make a new List of ArrayList from a List of ArrayList?

Time:03-08

Another silly question from a complete beginner.

I have a List<ArrayList<Boolean>> isExpenseByMonth with the following contents:

[[true, true, true, false, false, false], [true, true, false, false, false], [true, true, true, false, false, false]].

I need to "convert" boolean values to integers (true = -1, false = 1) and place them to a new List<ArrayList<Integer>> boolToIntByMonth so that it'd look like this (ArrayList<Integer>s should be of the same size as ArrayList<Boolean>s):

[[-1, -1, -1, 1, 1, 1], [-1, -1, 1, 1, 1], [-1, -1, -1, 1, 1, 1]]

So far I've tried to play around with the following code:

ArrayList<Integer> boolToInt = new ArrayList<>();
//List<ArrayList<Integer>> boolToIntByMonth = new ArrayList<>();
        
for (ArrayList<Boolean> arr : isExpenseByMonth) {
    for (boolean b : arr) {
        if (b) {
            boolToInt.add(-1);
            //boolToIntByMonth.add(boolToInt);
        } else {
            boolToInt.add(1);
            //boolToIntByMonth.add(boolToInt);
        }
    }   
}

But the best I could get is this (one ArrayList<Integer> with the correct values and order):

[-1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1]

Any help would be greatly appreciated.

CodePudding user response:

Your code has almost all the needed building blocks. The key missing part is creating a new ArrayList<Integer> in each iteration of the outer loop, like this:

ArrayList<ArrayList<Integer>> boolToIntByMonth = new ArrayList<>();
for (ArrayList<Boolean> arr : isExpenseByMonth) {
    ArrayList<Integer> boolToInt = new ArrayList<>();
    boolToIntByMonth.add(boolToInt);
    for (boolean b : arr) {
        if (b) {
            boolToInt.add(-1);
        } else {
            boolToInt.add(1);
        }
    }   
}

Then you can use the boolToIntByMonth as a List<ArrayList<Integer>>:

List<ArrayList<Integer>> result = boolToIntByMonth;

CodePudding user response:

Here is one way.

  • stream the original list of lists
  • then stream each list and map a boolean to the desired value.
  • creating a list of lists
List<List<Boolean>> lists = List.of(
        List.of(true, true, true, false, false, false),
        List.of(true, true, false, false, false),
        List.of(true, true, true, false, false, false));

List<List<Integer>> result = lists.stream()
    .map(list -> list.stream().map(v -> v ? -1 : 1)
        .toList())
    .toList();

result.forEach(System.out::println);

prints

[-1, -1, -1, 1, 1, 1]
[-1, -1, 1, 1, 1]
[-1, -1, -1, 1, 1, 1]

Note v ? -1 or 1 says if v is true, use -1 else use 1.

CodePudding user response:

In order to create a nested list (List<List<T>>) at each step of iteration of the outer for loop you have to create a new List and populate it with the data for the current month inside the inner for loop. This list needs to be added into the resulting nested list.

    List<List<Integer>> intByMonth = new ArrayList<>();

    for (List<Boolean> arr : isExpenseByMonth) {
        List<Integer> nextMonth = new ArrayList<>();
        for (boolean b : arr) {
            nextMonth.add(b ? -1 : 1);
        }
        intByMonth.add(nextMonth);
    }

Note:

  • Don't use concrete implementations like ArrayList as a type, it makes your code inflexible and unnecessarily verbose. Write the code against interfaces (List, Map, etc.). This approach is called Dependency inversion principle.
  • Related