我有2个包含重物的大列表,我需要将它们加入一个列表中。我的第一个直觉是创建一个新列表,并将这2个内容附加到其中,如下所示:

List<Item> items = new ArrayList<>();
items.addAll(list1);
items.addAll(list2);


但是,由于这是一个ArrayList以便复制这两个大列表,因此我需要分配新的内存,而不是使用现有内存一次并复制引用。

我现在的想法是使用LinkedList并将list1的结束节点复制到list2的头部,但是据我从文档中可以说的那样,没有这样的方法。

有没有更好的方法来串联2个列表而不重新分配新内存?如果没有,在这种情况下的最佳做法是什么?

最佳答案

这可能是内存/ GC最有效的方式:

List<Item> items = new ArrayList<>(list1.size() + list2.size());
items.addAll(list1);
items.addAll(list2);


诀窍是在创建列表时提供准确的capacity;参见javadoc。这样可以保存所有重复副本以“增长”目标列表(即list)。


  我现在的想法是使用LinkedList并将list1的结束节点复制到list2的头部,但是据我从文档中可以说的那样,没有这样的方法。


LinkedList每个列表项使用的内存比ArrayList更多。乘以4或更多。

此外,当您从一个addAll到另一个使用LinkedList时,您正在创建新的列表节点对象。




  我有2个包含重物的大清单....


物体的重量(大小)无关紧要。 List包含对对象的引用,而不是对象本身的副本。




  有没有更好的方法来串联2个列表而不重新分配新内存?


如果不分配更多内存,则无法串联两个java.util.List实例。您能做的最好的事情就是最小化分配。

另一方面...如果您准备实现自己的链接列表数据结构,则可以通过“拼接”将两个列表连接在一起。但是您List API不允许这种事情。 (首先,它会破坏原始列表。)



确实,过早的优化是一件坏事。但是,如果您已经有充分的证据表明所涉及的列表很大,那么可以说这还为时过早。

09-11 19:26
查看更多