简体   繁体   English

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

[英]How to efficiently merge two lists in Java?

There are several ways to merge lists in Java Java中有几种方法可以合并列表

  • You can call to ArrayList(Collection<? extends E> c)您可以调用ArrayList(Collection<? extends E> c)
  • You can use the stream API, like Stream.concat() or Stream.of(listA, listB).forEach() You can use the stream API, like Stream.concat() or Stream.of(listA, listB).forEach()
  • and more...和更多...

What would be the most memory and performance efficient way to merge two random access lists into a new random access list?将两个随机访问列表合并到一个新的随机访问列表中的最 memory 和性能有效的方法是什么?

You have not defined what "merge" means in your context.您尚未定义“合并”在您的上下文中的含义。 This answer assumes it means "combine into one list".这个答案假设它的意思是“合并到一个列表中”。

To reduce the amount of memory and processing used, create a List whose size is exactly right, then add each list in turn to it.为了减少 memory 的数量和使用的处理,创建一个大小完全正确的列表,然后将每个列表依次添加到它。

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

This eliminates possible redundant memory allocation and object creation that may occur during list1.addAll(list2) .这消除了可能在list1.addAll(list2)期间发生的冗余 memory 分配和 object 创建。

you can use Apache commons library -您可以使用Apache 公共库-

ListUtils.union(listA, listB);

Using parallel Java8 Streams could be is better instead of just streams for large datasets.使用并行 Java8 流可能会更好,而不仅仅是用于大型数据集的流。

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

Try this to create an immutable list containing all the elements, by performing a shallow copy.尝试通过执行浅拷贝来创建一个包含所有元素的不可变列表。 Beware that changes to the source lists will be reflected in the resulting list (so the immutability in reality depends on the immutability / access to the input lists).请注意,对源列表的更改将反映在结果列表中(因此实际上的不变性取决于对输入列表的不变性/访问)。

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

}

and

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

output output

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

Considering that the original list is updated, it might be better to remove the field size and do this:考虑到原始列表已更新,最好删除字段size并执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM