A list is an ordered collection in Java that can store any type of data, such as Int, String, etc. A List can have different sublists. This type of list is known as a nested list or list of lists. Flattening a list of lists means converting a nested/2D list into a single list. For example, we are given a nested list that contains three sublists as its elements. To flatten this nested list, all the sublists must turn into a single list, as demonstrated in the following image:
This article presents a comprehensive guide on flattening a list of lists in Java.
How to Flatten a List of Lists/Nested List in Java?
To flatten a list of lists in Java, use methods like “flatMap()”, “forEach()”, “reduce()”, or “collect()”. In addition to this, you can use the “forEach” loop, “Guava” Library, or “ Eclipse Collection” to flatten a nested list.
Before heading toward the implementation of these methods, let’s first create a string-type list of lists:
List<List<String>> empDetails = Arrays.asList(
Arrays.asList("Joseph", "Ambrose", "Seth"),
Arrays.asList("Author", "Team Lead", "Manager"),
Arrays.asList("Chicago", "New York", "Los Angeles"));
System.out.println("The Create ListOfLists: " + empDetails);
In this code, we execute “Arrays.asList()” several times to create a list of lists. Up next, we use the println() method to print the nested list on the console:
Now, let’s learn different methods to flatten this list into a single list.
Flattening a Nested/2D List Using flatMap()
In Java, flatMap() is the most convenient way of flattening a nested list. This method helps us convert each stream element into a new stream of elements, and then join these into a single stream. We can apply this method on a nested list to flatten it into a single list.
Let’s import the required classes like Lists, Arrays, and Collectors from the “java.util” package:
import java.util.*;
import java.util.stream.Collectors;
Now use the flatMap() method of the Java Stream API to flatten the given list of lists. Within the flatMap() method use the stream() and collect() methods. It is such that the stream() method flattens the given list of lists into a Stream and then the collect() method collects all elements into a particular collection:
List<String> flattenList = empDetails.stream().flatMap(listItem -> listItem.stream()).collect(Collectors.toList());
System.out.println("The Flattened List of Lists: \n" + flattenList);
The output demonstrates that the flatMap() method has successfully flatten the given List of lists:
Flattening a List of Lists Using for-each Loop
For-each or enhanced for loop is a classic and traditional approach to flattening a list of lists. To do this, first, create an empty list and then iterate the given nested list using the for each loop. Within the loop’s body, use the addAll() method to add the elements of the given list of lists into the empty list:
// creating a new empty list
List<String> flattenList = new ArrayList<>();
// Flattening Given ListOfLists
for (List<String> flatList : empDetails) {
flattenList.addAll(flatList);
}
System.out.println("\nThe Flattened List of Lists: \n" + flattenList);
At the end, use the println() method to print the flattened list on the console:
Flattening a List of Lists Using forEach() Method
forEach() is the easiest and most concise approach in Java to flatten a list of lists. To use this method, first, create an empty list and then apply the forEach() method on the given list of lists. Within the forEach() method, use the addAll with double dot operator to add the elements of the given nested list into the newly created empty list:
// creating a new empty list
List<String> flattenList = new ArrayList<>();
// Flattening Given ListOfLists
empDetails.forEach(flattenList::addAll);
System.out.println("\nThe Flattened List of Lists: \n" + flattenList);
On successful implementation of the forEach() method, you will get a flattening list as follows:
Flattening a List of Lists Using reduce() Method
The reduce() method performs a specific task on the provided stream and reduces it to a single value. You can utilize this method on a list of lists to convert it into a single list. It is such that, apply the reduce() method on the given lists and within the reduce() method use the addAll() method to add all elements into a single list. Store the resultant data in a new list named “flatenList”. Finally, print the flattened list on the console:
// Flattening Given ListOfLists
List<String> flattenList = empDetails.stream().reduce(new ArrayList<>(),(list1, list2) -> {
list1.addAll(list2);
return list1;
});
System.out.println("\nThe Flattened List of Lists: \n" + flattenList);
If you implement the reduce() method appropriately, you will get a flattened list as follows:
Flattening a List of Lists Using the collect() Method
This method performs mutable reduction operations on the provided stream, including flattening a nested list into a single list. Apply this method along with the stream() method to the given nested lists, and use addAll as its parameter. Finally, store the flattened list into a new list “flattenList” and print it on the console using the println():
// Flattening Given ListOfLists
List<String> flattenList = empDetails.stream().collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);
System.out.println("\nThe Flattened List of Lists: \n" + flattenList);
Flattening a List of Lists Using the Guava Library
Guava is an open-source third-party library and can be used to flatten a nested list. To use this library, first, we need to add the corresponding dependency for the Guava library in the pom.xml file of our Java project:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
Now let’s import the Iterables and Lists classes from the Guava Library, as follows:
import java.util.*;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
After importing the required libraries, create an iterable and use the concat() method to combine the nested list into a single list. Up next, use the “Lists.newArrayLists” to construct a flattened list from the specified iterable:
// Flattening Given ListOfLists
Iterable<String> iterable = Iterables.concat(empDetails);
List<String> flattenedList = Lists.newArrayList(iterable);
System.out.println("\nFlattered List: \n" + flattenedList);
If you didn’t make a mistake, you will get a flattened list something like this:
Flattening a List of Lists Using the Eclipse Collections
Another approach to performing the desired task is the use of Eclipse collections. It is a comprehensive collection framework that helps perform complicated tasks conveniently. You can use this framework to flatten a list of lists. For this, first, you need to add the latest dependency of the stated framework into our project:
<dependency> <groupId>org.eclipse.collections</groupId>
<artifactId>eclipse-collections</artifactId>
<version>11.1.0</version>
</dependency>
We add the stated dependency into the “pom.xml” file of our Maven project:
Now import the required classes and libraries at the start of your project:
import java.util.*;
import org.eclipse.collections.impl.list.mutable.ListAdapter;
After this use the flatCollect() method along with the adapt() method to flatten the given list of lists. Store the flattened list in a new list and print it on the console using the println() method:
// Flattening Given ListOfLists
List<String> flattenedList = ListAdapter.adapt(empDetails).flatCollect(emp -> emp);
System.out.println("\nFlattered List: \n" + flattenedList);
That’s all about flattening a nested List or list of lists in Java.
Final Thoughts
To flatten a list of lists in Java, you can use methods like “flatMap()”, “forEach()”, “reduce()”, and “collect()”. Also, you can use the “forEach” loop, “Guava” Library, or “ Eclipse Collection” to flatten a nested list in Java. In this Java post, all these methods are explained with appropriate examples. You can choose any of these method that suits you the best.