如何有效地合并 Java 中的两个列表?

How to efficiently merge two lists in Java?

在Java

中有几种合并列表的方法

将两个随机访问列表合并为一个新的随机访问列表的内存和性能最有效的方法是什么?

您尚未定义“合并”在您的上下文中的含义。这个答案假定它的意思是“合并成一个列表”。

要减少使用的内存和处理量,请创建一个大小恰到好处的列表,然后依次将每个列表添加到其中。

List<E> result = new ArrayList<>(list1.size() + list2.size());
result.addAll(list1);
result.addAll(list2);

这消除了 list1.addAll(list2) 期间可能发生的冗余内存分配和对象创建。

试试这个,通过执行浅拷贝来创建一个包含所有元素的不可变列表。请注意,对源列表的更改将反映在结果列表中(因此现实中的不变性取决于对输入列表的不变性/访问)。

public class MergedList<T> extends AbstractList<T> {

    private final List<T>[] lists;
    private final int size;

    @SafeVarargs
    MergedList(List<T>... lists) {
        this.lists = lists.clone();
        this.size = Arrays.stream(lists).mapToInt(list -> list.size()).sum();
    }

    @Override
    public T get(int index) {
        for (List<T> list : lists)
            if (index < list.size())
                return list.get(index);
            else
                index -= list.size();
        throw new IndexOutOfBoundsException("index");
    }

    @Override
    public int size() {
        return size;
    }

}

List<Integer> a = List.of(1, 2, 3, 4);
List<Integer> b = List.of(5, 6, 7);
List<Integer> c = new MergedList<>(a, b);
System.out.println(c);

输出

[1, 2, 3, 4, 5, 6, 7]

考虑到原始列表已更新,最好删除字段 size 并执行此操作:

    @Override
    public int size() {
        return Arrays.stream(lists).mapToInt(list -> list.size()).sum();
    }

你可以使用Apache commons library-

ListUtils.union(listA, listB);

对于大型数据集,使用并行 Java8 流可能比仅使用流更好。

Stream.concat(list1.parallelStream(), list1.parallelStream())
      .collect(Collectors.toList());