首页 文章

如何在Java 8中将列表列表转换为列表?

提问于
浏览
320

如果我有 List<List<Object>> ,如何通过使用Java 8的功能将其转换为包含相同迭代顺序中所有对象的 List<Object>

6 回答

  • 13

    正如@Saravana所说:

    flatmap更好,但还有其他方法可以达到同样的效果

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

    总而言之,有几种方法可以实现如下相同:

    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);
    }
    
  • 10

    您可以使用flatMap将内部列表(将它们转换为Streams后)展平为单个Stream,然后将结果收集到列表中:

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

    flatmap 更好,但还有其他方法可以实现同样的目标

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

    您可以使用Eclipse Collections中的 flatCollect() 模式 .

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

    如果您无法从 List 更改列表:

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

    注意:我是Eclipse Collections的贡献者 .

  • 601

    Stream 上的 flatMap 方法当然可以为这些列表压扁,但必须为元素创建 Stream 对象,然后为结果创建 Stream .

    您不需要所有 Stream 对象 . 以下是执行任务的简单,简洁的代码 .

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

    因为 ListIterable ,所以此代码调用the forEach method(Java 8特性),它继承自 Iterable .

    对Iterable的每个元素执行给定操作,直到处理完所有元素或操作抛出异常为止 . 如果指定了该顺序,则按迭代顺序执行操作 .

    并且 ListIterator 按顺序返回项目 .

    对于 Consumer ,此代码将方法引用(Java 8功能)传递给Java 8之前的方法List.addAll,以按顺序添加内部列表元素 .

    按指定集合的迭代器(可选操作)返回的顺序,将指定集合中的所有元素追加到此列表的末尾 .

  • 2

    我只想解释另一个场景,如 List<Documents> ,此列表包含其他文档的列表,如 List<Excel>List<Word>List<PowerPoint> . 所以结构是

    Class A{
      List<Documents> documentList
    }
    
    Class Documents{
      List<Excel> excels
      List<Word> words
      List<PowerPoint> ppt
    }
    

    现在,如果您只想从文档迭代Excel,那么执行以下操作 .

    所以代码就是

    List<Document> 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.
     }
    

    我希望这可以在编码时解决某人的问题 .

相关问题