从列表中删除项目或添加构建新列表?

时间:2015-09-24 14:46:17

标签: java collections

我常常需要迭代一个ArrayList,并希望根据任何条件从中创建一个子集。

从性能的角度来看:对于我想要删除的元素使用迭代器和iterator.remove()是否更好,或者我应该将这些元素添加到新列表中?

for (Iterator<Object> it = list.iterator(); it.hasNext(); ) {
    Object item = it.next();
    if (!conditionMatches(item)) {
        it.remove();
    }
}

List<Object> newList = new ArrayList<>();
for (Object item : list) {
   it (contitionMatches(item)) {
      newList.add(item);
   }
}

5 个答案:

答案 0 :(得分:4)

选项1 不适用于只读列表,例如Arrays.asList返回的列表。

此外,remove中的ArrayList是一个重要的代价,因为必须复制大部分支持数组才能列出该列表。

选项2 适用于所有列表。

这也是我们鼓励与流一起使用的模式:

    List<String> l = Arrays.asList("A","B","C");
    List<String> filtered = l.stream()
            .filter(s -> s.equals("A"))
            .collect(Collectors.toList());

恕我直言 - 使用这一个。选项1中的节省是虚幻的。

答案 1 :(得分:2)

时间复杂度:选项2最好

空间复杂性:选项1最好

ArrayList remove是O(n),而add是O(1),但是,你必须为新列表分配新的内存。

答案 2 :(得分:2)

如果您只需删除一个元素,则无论哪种方式都可以。如果要删除某个点之后的所有元素,可以采用任意一种方式(向后迭代以进行删除)。然而,一般而言,复制方法可能花费更少的时间。如果您希望修改列表,可以考虑removeIf。尽管文档没有说明它是如何工作的,但它很可能会跟踪“到”和“从”索引,在一次传递中将所有元素向下移动。复制或修改方法是否最合适肯定取决于您使用列表的方式,(如果我对removeIf的猜测是正确的话)也可能取决于删除了哪些元素。

答案 3 :(得分:0)

如果你想从列表中删除值,你需要从头到尾进行,如下所示:

for (int i=list.size()-1; i>=0; i--) {
   if (contitionMatches(list.get(i))) {
       list.remove(i);
   }
}

答案 4 :(得分:0)

第二个选项更快,因为当移除当前位置的元素时,它不涉及移动所有后续元素。

当谈到更大的ArrayList时,我甚至敢说第一种选择是反模式。