如何在Java中高效地合并两个列表



Java 中有几种合并列表的方法

  • 您可以呼叫ArrayList(Collection<? extends E> c)
  • 您可以使用流API,如Stream.concat()Stream.of(listA, listB).forEach()
  • 还有更多

将两个随机访问列表合并到一个新的随机访问列表中,最节省内存和性能的方法是什么?

您可以使用Apache公共库-

ListUtils.union(listA, listB);

使用并行Java8 Streams可能会更好,而不仅仅是用于大型数据集的流。

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

您还没有定义什么"合并";意思是在你的上下文中。这个答案假定它的意思是";组合成一个列表";。

为了减少使用的内存和处理量,创建一个大小正好合适的列表,然后依次添加每个列表。

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();
}

最新更新