Flattening Nested Collections in Java

1. Overview

In this quick article, we’ll explore how to flatten a nested collection in Java.

2. Example of a Nested Collection

Suppose we have a list of lists of type String.

List<List<String>> nestedList = asList(
  asList("one:one"), 
  asList("two:one", "two:two", "two:three"), 
  asList("three:one", "three:two", "three:three", "three:four"));

3. Flattening the List With forEach

In order to flatten this nested collection into a list of strings, we can use forEach together with a Java 8 method reference:

public <T> List<T> flattenListOfListsImperatively(
    List<List<T>> nestedList) {
    List<T> ls = new ArrayList<>();
    nestedList.forEach(ls::addAll);
    return ls;
}

And here you can see the method in action:

@Test
public void givenNestedList_thenFlattenImperatively() {
    List<String> ls = flattenListOfListsImperatively(nestedList);
    
    assertNotNull(ls);
    assertTrue(ls.size() == 8);
    assertThat(ls, IsIterableContainingInOrder.contains(
      "one:one",
      "two:one", "two:two", "two:three", "three:one",
      "three:two", "three:three", "three:four"));
}

4. Flattening the List With flatMap

We can also flatten the nested list by utilizing the flatMap method from the Stream API.

This allows us to flatten the nested Stream structure and eventually collect all elements to a particular collection:

public <T> List<T> flattenListOfListsStream(List<List<T>> list) {
    return list.stream()
      .flatMap(Collection::stream)
      .collect(Collectors.toList());    
}

And here’s the logic in action:

@Test
public void givenNestedList_thenFlattenFunctionally() {
    List<String> ls = flattenListOfListsStream(nestedList);
    
    assertNotNull(ls);
    assertTrue(ls.size() == 8);
}

5. Conclusion

A simple forEach or flatMap methods in Java 8, in combination with method references, can be used for flattening nested collections.

You can find the code discussed in this article over on GitHub.

Related posts:

Java Program to Represent Graph Using Incidence Matrix
Configuring a DataSource Programmatically in Spring Boot
Circular Dependencies in Spring
Hướng dẫn Java Design Pattern – DAO
Logging in Spring Boot
@DynamicUpdate with Spring Data JPA
Java Program to Implement Attribute API
ThreadPoolTaskExecutor corePoolSize vs. maxPoolSize
Java Switch Statement
Loại bỏ các phần tử trùng trong một ArrayList như thế nào?
Jackson Unmarshalling JSON with Unknown Properties
@Lookup Annotation in Spring
Java Program to Implement Triply Linked List
HttpClient with SSL
Java Program to Check whether Graph is Biconnected
Java Program to Implement the String Search Algorithm for Short Text Sizes
Java Program to Implement LinkedHashMap API
Java Program to Implement Heap Sort Using Library Functions
Guide to System.gc()
Java Program to Check whether Graph is a Bipartite using 2 Color Algorithm
Guide to @JsonFormat in Jackson
Simplify the DAO with Spring and Java Generics
Java Program to Implement Skew Heap
Spring Boot - Quick Start
JUnit5 Programmatic Extension Registration with @RegisterExtension
Java Program to Implement Bresenham Line Algorithm
Java Program to Optimize Wire Length in Electrical Circuit
Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman
Hướng dẫn Java Design Pattern – Intercepting Filter
Java Program to Find Maximum Element in an Array using Binary Search
The DAO with Spring and Hibernate
Java Program to Find the Vertex Connectivity of a Graph