从ArrayList中删除多个元素

时间:2011-02-09 21:27:33

标签: java arraylist

我有一堆索引,我想从ArrayList删除这些索引中的元素。我不能做remove() s的简单序列,因为每次删除后元素都会移位。我该如何解决这个问题?

16 个答案:

答案 0 :(得分:38)

要删除indexes处的元素:

Collections.sort(indexes, Collections.reverseOrder());
for (int i : indexes)
    strs.remove(i);

或者,使用Java 8中的Stream API:

indexes.sort(Comparator.reverseOrder());
indexes.stream().mapToInt(i -> i).forEach(l::remove);

答案 1 :(得分:28)

按降序对索引进行排序,然后逐个删除它们。如果你这样做,删除将无法影响你以后想要删除的任何索引。

如何对它们进行排序取决于您用于存储索引的集合。如果是列表,您可以这样做:

List<Integer> indices;
Collections.sort(indices, new Comparator<Integer>() {
   public int compare(Integer a, Integer b) {
      //todo: handle null
      return b.compareTo(a);
   }
}

修改

@aioobe找到了我找不到的助手。而不是上述,您可以使用

Collections.sort(indices, Collections.reverseOrder());

答案 2 :(得分:4)

我来这里是为了删除特定范围内的元素(即2个索引之间的所有元素),并发现了这个:

list.subList(indexStart, indexEnd).clear()

答案 3 :(得分:3)

您可以从最大索引向下删除元素,或者如果您有对要删除的对象的引用,则可以使用removeAll方法。

答案 4 :(得分:3)

您可以按相反顺序删除索引。如果索引的顺序如1,2,3,则可以removeRange(1,3)。

答案 5 :(得分:2)

我认为nanda是正确答案。

List<T> toRemove = new LinkedList<T>();
for (T t : masterList) {
  if (t.shouldRemove()) {
    toRemove.add(t);
  }
}

masterList.removeAll(toRemove);

答案 6 :(得分:1)

如果要删除的元素非常多(以及长列表),则迭代列表并将所有不要删除的元素添加到新列表中可能会更快,因为每个remove() - 数组列表中的步骤将逐个删除后的所有元素。在这种情况下,如果您的索引列表尚未排序(并且您可以与主列表并行迭代),您可能希望为{{使用HashSet或BitSet或类似的O(1)-access-structure结构1}}检查:

contains()

答案 7 :(得分:0)

订购索引列表,例如

如果2,12,9,7,3订购desc到12,9,7,3,2

然后执行此操作

for(var i = 0; i < indexes.length; i++) { source_array.remove(indexes[0]); }

这可以解决您的问题。

答案 8 :(得分:0)

如果要删除的元素全部组合在一起,则可以执行subList(start, end).clear()操作。

如果您要删除的元素是分散的,最好创建一个新的ArrayList,只添加您想要包含的元素,然后将其复制回原始列表。

编辑:我现在意识到这不是性能问题,而是逻辑问题。

答案 9 :(得分:0)

您可以对索引进行排序,或者您可以使用迭代器并调用remove()

List<String> list = new ArrayList<String>();
    list.add("0");
    list.add("1");
    list.add("2");
    list.add("3");
    list.add("4");
    list.add("5");
    list.add("6");
    List<Integer> indexes = new ArrayList<Integer>();
    indexes.add(2);
    indexes.add(5);
    indexes.add(3);
    int cpt = 0;
    Iterator<String> it = list.iterator(); 
    while(it.hasNext()){
        it.next();
        if(indexes.contains(cpt)){
            it.remove();
        }
        cpt++;
    }

这取决于你需要什么,但在大多数情况下排序会更快

答案 10 :(得分:0)

使用guava!您正在寻找的方法是 Iterators.removeAll(Iterator removeFrom,Collection elementsToRemove)

答案 11 :(得分:0)

您可能希望将subList方法与要删除的索引范围一起使用 然后在上面调用clear()。

(注意排除最后一个参数,只删除第一个和第二个元素):

public static void main(String[] args) {
    // TODO Auto-generated method stub
    ArrayList<String> animals = new ArrayList<String>();
    animals.add("cow");
    animals.add("dog");
    animals.add("chicken");
    animals.add("cat");
    animals.subList(0, 2).clear();
    for(String s:animals)
        System.out.println(s);
}

}

结果将是: 鸡 猫

答案 12 :(得分:0)

如果要将位置X移除到尺寸

//a is the ArrayList
a=(ArrayList)a.sublist(0,X-1);

答案 13 :(得分:0)

假设您的indexes数组已排序(例如:1,3,19,29),您可以这样做:

for (int i = 0; i < indexes.size(); i++){
   originalArray.remove(indexes.get(i) - i);
}

答案 14 :(得分:0)

我想我上面没有看到的一种更有效的方法是创建一个新的Arraylist并通过将它们复制到新数组来选择哪些索引存活。最后重新分配参考文献。

答案 15 :(得分:0)

我最终在这里找到了类似的查询,@ aioobe的回答帮助我找到了解决方案。 但是,如果要填充要自行删除的索引列表,可能需要考虑使用this

indices.add(0, i);

这将消除在迭代之前对列表进行(昂贵的)反向排序的需要,同时从主ArrayList中删除元素。