【问题标题】:Combine multiple lists in Java在 Java 中合并多个列表
【发布时间】:2017-12-30 02:10:23
【问题描述】:

如果我想在 Java 中将两个列表合二为一,我可以使用ListUtils.union(List list1,List list2)。但是如果我想合并多个列表呢?

这行得通:

import org.apache.commons.collections.ListUtils;
List<Integer>list1=Arrays.asList(1,2,3);
List<Integer>list2=Arrays.asList(4,5,6);
List<Integer>list3=Arrays.asList(7,8,9);
List<Integer>list4=Arrays.asList(10,0,-1);
System.out.println(ListUtils.union(ListUtils.union(list1, list2),ListUtils.union(list3, list4)));

但它看起来并不是最好的解决方案,阅读起来也不是特别好。可悲的是ListUtils.union(list1,list2,list3,list4) 不起作用。多次使用addAll 并为此创建自己的列表,其中所有条目的重复项对我来说似乎也不理想。那我能做什么呢?

【问题讨论】:

  • ListUtils 不是标准的 Java API 类。您指的是 apache-commons ListUtils 类吗?如果是这样,请编辑您的问题以明确说明。
  • @Bit 谁说这个 OP 用的是 Guava?你的副本是一个专门询问番石榴的问题,答案也是使用番石榴
  • @MickMnemonic 动物也是猫?
  • @MickMnemonic 不,不是。我没有重新打开它——我认为 Ghostcat 是在他意识到这不是一个正确的副本之后自己做了的。如果有人问如何在没有提及特定库的情况下组合列表,那么询问并回答如何使用 Guava 组合 Iterables 的问题不是正确的重复。
  • 既然人们似乎已经得出结论,这不是一个重复的问题,有人可以告诉我为什么它仍然被认为是一个坏问题吗?它有两个反对票。

标签: java list


【解决方案1】:

使用 ArrayList 列出所有列表...

ArrayList<String> arrl = new ArrayList<String>();
List<String> list1 = new ArrayList<String>();
    list.add("one");
    list.add("two");
List<String> list2 = new ArrayList<String>();
    list.add("one1");
    list.add("two2");
    arrl.addAll(list1);
arrl.addAll(list2);
    System.out.println("After Copy: "+arrl);

这就是你的清单

【讨论】:

    【解决方案2】:

    Stream API 的帮助下,Java 8 提供了一种简单的方法,如下面的代码所示。我们基本上已经创建了一个包含所有列表的流,然后由于我们需要列表的各个内容,因此需要使用 flatMap 将其展平,最后将元素收集到 List 中。

    List<Integer>list1=Arrays.asList(1,2,3);
    List<Integer>list2=Arrays.asList(4,5,6);
    List<Integer>list3=Arrays.asList(7,8,9);
    List<Integer>list4=Arrays.asList(10,0,-1);
    List<Integer> newList = Stream.of(list1, list2, list3,list4)
                                          .flatMap(Collection::stream)
                                          .collect(Collectors.toList());       
     System.out.println(newList); // prints [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, -1]
    

    【讨论】:

    • 似乎有人出于某种原因清除了这里的 cmets。这是一个存档:web.archive.org/web/20170725052617/https://stackoverflow.com/… 另外,我记得有人说“这是很多开销”,这可能是为了指出到流和返回的转换是昂贵的操作。为了提高性能,使用addAll 会更好,尤其是因为向一个列表中添加许多元素不能有效地进行多线程处理。哇,自从问了这个问题,我学到了很多!
    • 要删除重复的项目,请使用 Collectors.toSet() 而不是 list..
    【解决方案3】:

    您可以编写自己的方法来合并两个或多个列表。示例:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    public class Test{ 
        public static void main(String[] args) {
            List<Integer>list1 = Arrays.asList(1,2,3);
            List<Integer>list2 = Arrays.asList(4,5,6);
            List<Integer>list3 = Arrays.asList(7,8,9);
            List<Integer>list4 = Arrays.asList(10,0,-1);
    
            System.out.println(combineMyLists(list1,list2,list3,list4));
            System.out.println("----------------------");
            System.out.println(combineMyLists2(list1,list2,list3,list4));
        } 
        private static List<Integer> combineMyLists(List<Integer>... args) {
            List<Integer> combinedList = new ArrayList<>();
            for(List<Integer> list : args){
                for(Integer i: list){
                   combinedList.add(i);
                }
            }
            return combinedList;
        }
        private static List<Integer> combineMyLists2(List<Integer>... args) {
            List<Integer> combinedList = Stream.of(args).flatMap(i -> i.stream()).collect(Collectors.toList());   ;
            return combinedList;
        }
    }
    

    【讨论】:

      【解决方案4】:

      添加其他选择:

      选项 1:

      List<Integer> joinedList = joinLists(list1, list2, list3, list4);
      
      public static <T> List<T> joinLists(List<T>... lists) {
              return Arrays.stream(lists).flatMap(Collection::stream).collect(Collectors.toList()); 
      }
      

      选项 2:

      List<Integer> joinedList = new ArrayList<>();
      Stream.of(list1, list2, list3, list4).forEach(joinedList::addAll);
      

      【讨论】:

      • 我比建议的答案更喜欢这个,即使它非常相似,因为它更干净。使用流 api 和 reduce 函数,这甚至可以更加精简,因此不再需要单独的“新 ArrayList”。
      • 请注意,如果列表中有大量元素,则您的引用会多次保存在内存中。在此处查看使用原始列表检索数据stackoverflow.com/a/13868352/11152683
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 2013-10-10
      • 2021-11-13
      • 1970-01-01
      • 2019-08-06
      相关资源
      最近更新 更多