复制部分ArrayList比我正在做的更有效/更快/更敏感吗?
public ArrayList<FooObject> getListOfFlagged() {
for(FooObject fooObject: foos) {
//for each item in the original array, where the item isFlagged...
if(fooObject.isFlagged) {
someOtherArray.add(fooObject);
}
}
return someOtherArray;
}
答案 0 :(得分:3)
您可以使用Collections2.filter()
中的guava
方法。它看起来更具功能性:
Collections2.filter(foos, new Predicate<FooObject>() {
@Override
public boolean apply(FooObject input) {
return fooObject.isFlagged();
}
})
结果由原始foos
集合支持,因此如果您需要副本,则必须使用new ArrayList<FooObject>(filteredCollection)
制作防御性副本。
答案 1 :(得分:1)
使用番石榴:
class FooObject{boolean isFlagged(){return true;}}
List<FooObject> foos = Lists.newArrayList();
Lists.newArrayList(
Iterables.filter(foos, new Predicate<FooObject>(){
@Override public boolean apply(FooObject input) {
return input.isFlagged();
};
})
);
答案 2 :(得分:0)
否则没有,除非您对需要复制的元素的位置有所了解。
说,您需要复制50个元素数组的元素10-19,然后分配10个元素的数组,使用System.arrayCopy()
会更快。
答案 3 :(得分:0)
一个重要的优化是预先分配“someOtherArray”中的元素数量,因为否则它会进行许多重新分配 - 当然,这取决于您要处理的项目数量。由于我们事先并不知道结果大小,最简单的方法是使用
将someOtherArray
的容量设置为foos
的大小
someOtherArray.ensureCapacity(foos.size());
当然,如果foos
很大并且通常只会标记一些项目,那么这是没有意义的。
另请注意,您的方法应该首先清除()someOtherArray。
我能想到的另一个优化是如何访问foos
的元素。您可以尝试使用典型的for (int i = 0; i < size; i++)
循环,并使用fooObject
初始化foos.get(i)
。如果通过获取数组中元素的副本来实现“extended for”,或者也可能获得迭代器,那么这种方式可能会更快。但我认为迭代ArrayList会在编译器中获得特殊优化......也许其他人在该领域有经验。