How can I turn a List of Lists into a List in Java 8?

JavaCollectionsJava 8

Java Problem Overview


If I have a List<List<Object>>, how can I turn that into a List<Object> that contains all the objects in the same iteration order by using the features of Java 8?

Java Solutions


Solution 1 - Java

You can use flatMap to flatten the internal lists (after converting them to Streams) into a single Stream, and then collect the result into a list:

List<List<Object>> list = ...
List<Object> flat = 
    list.stream()
        .flatMap(List::stream)
        .collect(Collectors.toList());

Solution 2 - Java

flatmap is better but there are other ways to achieve the same

List<List<Object>> listOfList = ... // fill

List<Object> collect = 
      listOfList.stream()
                .collect(ArrayList::new, List::addAll, List::addAll);

Solution 3 - Java

The flatMap method on Stream can certainly flatten those lists for you, but it must create Stream objects for element, then a Stream for the result.

You don't need all those Stream objects. Here is the simple, concise code to perform the task.

// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);

Because a List is Iterable, this code calls the forEach method (Java 8 feature), which is inherited from Iterable.

> Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Actions are performed in the order of iteration, if that order is specified.

And a List's Iterator returns items in sequential order.

For the Consumer, this code passes in a method reference (Java 8 feature) to the pre-Java 8 method List.addAll to add the inner list elements sequentially.

> Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's iterator (optional operation).

Solution 4 - Java

Method to convert a List<List> to List :

listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());

See this example:

public class Example {

    public static void main(String[] args) {
		List<List<String>> listOfLists = Collections.singletonList(Arrays.asList("a", "b", "v"));
        List<String> list = listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());

        System.out.println("listOfLists => " + listOfLists);
        System.out.println("list => " + list);
    }

}       

It prints:

listOfLists => [[a, b, c]]
list => [a, b, c]

In Python this can be done using List Comprehension.

list_of_lists = [['Roopa','Roopi','Tabu', 'Soudipta'],[180.0, 1231, 2112, 3112], [130], [158.2], [220.2]]

flatten = [val for sublist in list_of_lists for val in sublist]

print(flatten)
['Roopa', 'Roopi', 'Tabu', 'Soudipta', 180.0, 1231, 2112, 3112, 130, 158.2, 220.2]

Solution 5 - Java

Just as @Saravana mentioned:

> flatmap is better but there are other ways to achieve the same

 listStream.reduce(new ArrayList<>(), (l1, l2) -> {
        l1.addAll(l2);
        return l1;
 });

To sum up, there are several ways to achieve the same as follows:

private <T> List<T> mergeOne(Stream<List<T>> listStream) {
    return listStream.flatMap(List::stream).collect(toList());
}

private <T> List<T> mergeTwo(Stream<List<T>> listStream) {
    List<T> result = new ArrayList<>();
    listStream.forEach(result::addAll);
    return result;
}

private <T> List<T> mergeThree(Stream<List<T>> listStream) {
    return listStream.reduce(new ArrayList<>(), (l1, l2) -> {
        l1.addAll(l2);
        return l1;
    });
}

private <T> List<T> mergeFour(Stream<List<T>> listStream) {
    return listStream.reduce((l1, l2) -> {
        List<T> l = new ArrayList<>(l1);
        l.addAll(l2);
        return l;
    }).orElse(new ArrayList<>());
}

private <T> List<T> mergeFive(Stream<List<T>> listStream) {
    return listStream.collect(ArrayList::new, List::addAll, List::addAll);
}

Solution 6 - Java

I just want to explain one more scenario like List<Documents>, this list contains a few more lists of other documents like List<Excel>, List<Word>, List<PowerPoint>. So the structure is

class A {
  List<Documents> documentList;
}

class Documents {
  List<Excel> excels;
  List<Word> words;
  List<PowerPoint> ppt;
}

Now if you want to iterate Excel only from documents then do something like below..

So the code would be

 List<Documents> documentList = new A().getDocumentList();

 //check documentList as not null

 Optional<Excel> excelOptional = documentList.stream()
					     .map(doc -> doc.getExcel())
					     .flatMap(List::stream).findFirst();
 if(excelOptional.isPresent()){
   Excel exl = optionalExcel.get();
   // now get the value what you want.
 }

I hope this can solve someone's issue while coding...

Solution 7 - Java

You can use the flatCollect() pattern from Eclipse Collections.

MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);

If you can't change list from List:

List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);

Note: I am a contributor to Eclipse Collections.

Solution 8 - Java

An expansion on Eran's answer that was the top answer, if you have a bunch of layers of lists, you can keep flatmapping them.

This also comes with a handy way of filtering as you go down the layers if needed as well.

So for example:

List<List<List<List<List<List<Object>>>>>> multiLayeredList = ...

List<Object> objectList = multiLayeredList
    .stream()
    .flatmap(someList1 -> someList1
        .stream()
        .filter(...Optional...))
    .flatmap(someList2 -> someList2
        .stream()
        .filter(...Optional...))
    .flatmap(someList3 -> someList3
        .stream()
        .filter(...Optional...))
    ...
    .collect(Collectors.toList())

This is would be similar in SQL to having SELECT statements within SELECT statements.

Solution 9 - Java

We can use flatmap for this, please refer below code :

 List<Integer> i1= Arrays.asList(1, 2, 3, 4);
 List<Integer> i2= Arrays.asList(5, 6, 7, 8);
 
 List<List<Integer>> ii= Arrays.asList(i1, i2);
 System.out.println("List<List<Integer>>"+ii);
 List<Integer> flat=ii.stream().flatMap(l-> l.stream()).collect(Collectors.toList());
 System.out.println("Flattened to List<Integer>"+flat);
 

Solution 10 - Java

Since [tag:java-16], you can use Stream#mapMulti

List<Object> result = listOfLists.stream()
                                 .mapMulti((List<Object> list, Consumer<Object> consumer) -> {
                                     list.forEach(consumer::accept);
                                 })
                                 .collect(Collectors.toList());

If you need an immutable List you can even use toList() as terminal operation

List<Object> result = listOfLists.stream()
                                 .mapMulti((List<Object> list, Consumer<Object> consumer) -> {
                                     list.forEach(consumer::accept);
                                 })
                                 .toList();

Solution 11 - Java

List> list = map.values().stream().collect(Collectors.toList());

 	List<Employee> employees2 = new ArrayList<>();
    
     list.stream().forEach(
    		 
    		 n-> employees2.addAll(n));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSarah SzaboView Question on Stackoverflow
Solution 1 - JavaEranView Answer on Stackoverflow
Solution 2 - JavaSaravanaView Answer on Stackoverflow
Solution 3 - JavargettmanView Answer on Stackoverflow
Solution 4 - JavaSoudipta DuttaView Answer on Stackoverflow
Solution 5 - JavaHearenView Answer on Stackoverflow
Solution 6 - JavaKushwahaView Answer on Stackoverflow
Solution 7 - JavaNikhil NanivadekarView Answer on Stackoverflow
Solution 8 - Javacody.tv.weberView Answer on Stackoverflow
Solution 9 - JavaPratik PawarView Answer on Stackoverflow
Solution 10 - JavaYassin HajajView Answer on Stackoverflow
Solution 11 - Javanagendra babuView Answer on Stackoverflow