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

后端 未结 9 595
春和景丽
春和景丽 2020-11-22 04:49

If I have a List>, how can I turn that into a List that contains all the objects in the same iteration order
相关标签:
9条回答
  • 2020-11-22 05:05

    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]
    
    0 讨论(0)
  • 2020-11-22 05:06

    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);
    
    0 讨论(0)
  • 2020-11-22 05:07

    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.

    0 讨论(0)
  • 2020-11-22 05:12

    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);
    
    0 讨论(0)
  • 2020-11-22 05:14

    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());
    
    0 讨论(0)
  • 2020-11-22 05:23

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

    0 讨论(0)
提交回复
热议问题