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 usinglist.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]