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.


» 下一篇: Java 2017调查报告