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

huangapple go评论76阅读模式
英文:

How to efficiently merge two lists in Java?

问题

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

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

哪种方法对于将两个随机访问列表合并成一个新的随机访问列表来说最节省内存和性能最高?

英文:

There are several ways to merge lists in Java

  • You can call to ArrayList(Collection&lt;? extends E&gt; c)
  • 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?

答案1

得分: 5

Sure, here's the translation:

你可以使用Apache commons库-

ListUtils.union(listA, listB);

对于大型数据集,使用并行的Java 8 Streams 可能比仅使用Streams更好。

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

you can use Apache commons library-

ListUtils.union(listA, listB);

Using parallel Java8 Streams could be is better instead of just streams for large datasets.

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

答案2

得分: 4

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

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

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

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

英文:

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.

List&lt;E&gt; result = new ArrayList&lt;&gt;(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).

答案3

得分: 1

以下是您要翻译的代码部分:

尝试使用此方法创建包含所有元素的不可变列表,通过执行浅复制。请注意,对源列表的更改将反映在结果列表中(因此实际上的不可变性取决于输入列表的不可变性/访问)。

public class MergedList&lt;T&gt; extends AbstractList&lt;T&gt; {

    private final List&lt;T&gt;[] lists;
    private final int size;

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

    @Override
    public T get(int index) {
        for (List&lt;T&gt; list : lists)
            if (index &lt; list.size())
                return list.get(index);
            else
                index -= list.size();
        throw new IndexOutOfBoundsException(&quot;index&quot;);
    }

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

}

以及

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

输出

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

考虑到原始列表已更新最好删除字段 `size` 并执行以下操作

    @Override
    public int size() {
        return Arrays.stream(lists).mapToInt(list -&gt; list.size()).sum();
    }
英文:

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&lt;T&gt; extends AbstractList&lt;T&gt; {

    private final List&lt;T&gt;[] lists;
    private final int size;

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

    @Override
    public T get(int index) {
        for (List&lt;T&gt; list : lists)
            if (index &lt; list.size())
                return list.get(index);
            else
                index -= list.size();
        throw new IndexOutOfBoundsException(&quot;index&quot;);
    }

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

}

and

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

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:

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

huangapple
  • 本文由 发表于 2020年8月11日 07:26:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63349403.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定