【发布时间】:2016-12-20 02:31:34
【问题描述】:
我发现自己经常做以下事情:
Iterator<A> itr = iterableOfA.getIterator();
List<B> list = new ArrayList<>(); // how about LinkedList?
while (itr.hasNext()) {
B obj = iter.next().getB();
list.add(obj);
}
someMethod(list); // this method takes an Iterable
我不知道iterableOfA 中可能有多少元素——可能是 5,可能是 5000。在这种情况下,LinkedList 会是一个更好的实现吗(因为list.add(obj) 会那么是 O(1))?就目前而言,如果 iterableOfA 有 5000 个元素,这将导致 list 的支持数组的许多大小调整。
其他选项是:
Iterator<A> itr = iterableOfA.getIterator();
int size = Iterables.size(iterableOfA); // from Guava
List<B> list = new ArrayList<>(size);
// and the rest...
这意味着iterableOfA 的双重迭代。当迭代的大小未知并且变化很大时,哪个选项最好:
- 只需使用
ArrayList。 - 只需使用
LinkedList。 - 计算
iterableOfA中的元素并分配一个ArrayList。
编辑 1
澄清一些细节:
- 我主要针对性能进行优化,其次针对内存使用进行优化。
-
list是一个短暂的分配,因为在请求结束时,任何代码都不应持有对它的引用。
编辑 2
对于我的具体情况,我意识到 someMethod(list) 不能处理超过 200 个元素的可迭代对象,因此我决定使用 new ArrayList<>(200),这对我来说已经足够好了。
但是,在一般情况下,我更愿意实施已接受答案中概述的解决方案(包装在自定义迭代中,无需分配列表)。
所有其他答案都对ArrayList 与LinkedList 的比较提供了宝贵的见解,因此我代表广大的 SO 社区感谢大家!
【问题讨论】:
标签: java performance list memory-management