How to convert a List of Lists into a List in Java 8

The Java List is an ordered collection that helps to insert, delete or search elements of any type(List) based on index positions.

You can use Java 8 Stream .flatMap() method or .mapMulti() method to convert List of Lists into an List

In this tutorial, you will learn how to convert a List of Lists into a List using Java 8 features.

Using .flatMap()

The Java 8 Stream .flatMap() method accepts a mapper function that applies on each element of the List to produce a new Stream.
To get a List from List of Lists using .flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) function,

  • Iterate the List of Lists using List.stream().
  • Invoke the .flatMap() with a mapper function(List::stream) to return Stream of elements.
  • Convert the stream of elements to a List using .collect(Collectors.toList()).

Use this method to make a simple implementation for combining a List of Lists into a List.

Code

    import java.util.Arrays;  
    import java.util.List;  
    import java.util.stream.Collectors;

    //main
    List<String> class1 = Arrays.asList("Alex","Bala","Raj");  
    List<String> class2 = Arrays.asList("Jessica","Micheal","Priya");  
    List<List<String>> studentsByClass = Arrays.asList(class1, class2);
    System.out.println(studentsByClass);  //[[Alex, Bala, Raj], [Jessica, Micheal, Priya]]

    List<String> students = studentsByClass.stream().flatMap(List::stream).collect(Collectors.toList());  
    System.out.println(students);  //[Alex, Bala, Raj, Jessica, Micheal, Priya]

Using .mapMulti()

The Java 16 Stream introduces the .mapMulti() function, which accepts BiConsumer mapper function that generates replacement elements and returns a new Stream.
To convert a List of Lists using .mapMulti(BiConsumer<? super T, ? super Consumer<R>> mapper),

  • Iterate the List of Lists using List.stream().
  • Invoke the .mapMulti() by passing two arguments, the type of element to be replaced(our case: List<String>) and the consumer function to generate the replacement element
  • Iterate each element in the List and return those elements using the consumer function.

Use this method to manipulate or apply some condition on the List before adding it to a new List.

Code

    import java.util.List;  
    import java.util.function.Consumer;  
    import java.util.stream.Collectors;

    //main
    List<String> class1 = Arrays.asList("Alex", "Bala", "Raj");  
    List<String> class2 = Arrays.asList("Jessica", "Micheal", "Priya");  
    List<List<String>> studentsByClass = Arrays.asList(class1, class2);  
    System.out.println(studentsByClass);  //[[Alex, Bala, Raj], [Jessica, Micheal, Priya]]

    List<String> students = studentsByClass.stream().mapMulti((List<String> list, Consumer<String> consumer) -> {  
    list.forEach(consumer::accept);  
    }).collect(Collectors.toList());  

    System.out.println(students);  //[Alex, Bala, Raj, Jessica, Micheal, Priya]

In the above example, a List of Lists(studentsByClass(class1 and class2)) are converted to a List(students) using the .mapMulti().

Using .reduce()

The Java Stream .reduce() accepts an accumulator function for combining two values and returns the result.
To convert a List of Lists into a List using the reduce(BinaryOperator<T> accumulator) function,

  • Iterate the List of Lists using .stream().
  • Invoke the .reduce() function passing accumulator function(x, y) referring the first and second List.
  • Inside the function, initialize a list with the first element(x).
  • Add all elements of the second list(y) to the first List using list.addAll(y)
  • Return the combined List.

This method combines just one hierarchy of a List of Lists.

Code

    import java.util.ArrayList;  
    import java.util.Arrays;  
    import java.util.List;  
    import java.util.function.Consumer;  
    import java.util.stream.Collectors;

    //main
    List<Student> class1 = Arrays.asList(Student.builder().id(101).name("Alex").build(), Student.builder().id(102).name("Bala").build());  
    List<Student> class2 = Arrays.asList(Student.builder().id(201).name("Jessica").build(), Student.builder().id(202).name("Priya").build());  
    List<List<Student>> studentsByClass = Arrays.asList(class1, class2);  
    System.out.println(studentsByClass);  //[[Student(name=Alex, id=101), Student(name=Bala, id=102)], [Student(name=Jessica, id=201), Student(name=Priya, id=202)]]

    List<Student> students = studentsByClass.stream().reduce((x, y) -> {  
        List<Student> list = new ArrayList<>(x);  
        list.addAll(y);  
        return list;  
    }).orElse(new ArrayList<>());  
    System.out.println(students);  //[Student(name=Alex, id=101), Student(name=Bala, id=102), Student(name=Jessica, id=201), Student(name=Priya, id=202)]

Using forEach()

The Java 8 Stream .forEach() function will iterate through each list and add to another new List.
To convert a List of Lists to a List using forEach(Consumer<? super T> action),

  • Create and Initialize a new List.
  • Iterate the List of Lists using .stream().
  • Add each iterated List to the new List.

Use this method to perform additional operations like printing the values in the List.

Code

    import java.util.ArrayList;  
    import java.util.Arrays;  
    import java.util.List;  

    //main
    List<Integer> oddNumbers = Arrays.asList(1,3,5,7,9);  
    List<Integer> evenNumbers = Arrays.asList(2,4,6,8,10);  
    List<List<Integer>> numbersList = Arrays.asList(oddNumbers, evenNumbers);  
    System.out.println(numbersList);  //[[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]

    List<Integer> numbers = new ArrayList<>();  
    numbersList.stream().forEach(n-> numbers.addAll(n));  
    System.out.println(numbers);  //[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]

Related Topics

Leave a Comment