从ArrayList中移除项目

105

我有一个名为listArrayList,其中包含8个项A-H,现在我想从list中删除存储在整数数组中的第1、3和5位置的项,该怎么做?

我正在尝试使用以下方法:

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
list.add("G");
list.add("H");

int i[] = {1,3,5};

for (int j = 0; j < i.length; j++) {
    list.remove(i[j]);
}

但在删除第一个元素后,数组的位置发生了变化,在下一次迭代中它会删除错误的元素或抛出异常。


1
按索引降序删除它怎么样(对索引进行排序,然后先删除具有最高索引的元素)? - nhahtdh
1
你的逻辑有误。你不应该考虑每个项目的位置,而是要考虑项目本身。换句话说,你不想删除位置1、3和5,而是想使用equals("B")equals("D")equals("F")List中删除项目(无论它们在哪里)。好好想一想。 - Squonk
是的,我想删除这个条目,但是如何匹配这些项目呢?实际上,在现实中,这些项目在ListView中,并且在选择后,我希望从DB和Array中删除它们并刷新适配器和列表。 - Krishnakant Dalal
慢速选项:迭代一次,将元素添加到第二个列表中,迭代第二个列表并从第一个列表中删除(可选步骤:将第二个列表返回给调用者)。 - SparK
11个回答

141

在这个特定的情况下,你应该按降序删除元素。先删除索引为5,然后是3,最后是1。这样将从列表中删除元素,而不会产生不良副作用。

for (int j = i.length-1; j >= 0; j--) {
    list.remove(i[j]);
}

1
OP的ArrayList包含“String”而不是“Integer”(尽管如此,我同意您的观察)。 - Alex Lockwood
@Alex:这个答案可以工作,但它和OP在问题中的逻辑一样有缺陷。我们正在谈论ArrayList<E> - 为什么任何人都想纯粹基于位置从ArrayList中删除对象,而不是测试该位置上的内容?OP可能会将String用作ArrayList的对象类型,但即使它解决了OP的特定情况,你的答案对于泛型来说真的是糟糕的编码实践。 - Squonk
3
我同意你的观点。但是OP提到的是ArrayList<String>,而不是ArrayList<E> - Adrian Monk
@hotveryspicy:就我而言,您的答案最接近正确答案。 - Squonk
68
好的,听着...我不知道有什么大不了的。那个发帖者发布了他的代码,我回答了一个可能解决问题的答案。很抱歉我没有超出范围给出完全通用的解决方案...但据我所知,发帖者并没有要求一节编程课。他是在问“为什么这段代码不起作用?”不要因为你对问题的理解不同就开始责怪我给你的回答打负分。 - Alex Lockwood
显示剩余3条评论

30

您可以使用ListIteratorArrayList中删除元素。

ListIterator listIterator = List_Of_Array.listIterator();

 /* Use void remove() method of ListIterator to remove an element from List.
     It removes the last element returned by next or previous methods.
 */
listIterator.next();

//remove element returned by last next method
listIterator.remove();//remove element at 1st position
listIterator.next();
listIterator.next();
listIterator.remove();//remove element at 3rd position
listIterator.next();
listIterator.next();
listIterator.remove();//remove element at 5th position

在Java中,从集合中删除对象时最好使用ListIterator remove()方法,并且这是一个良好的实践。因为有可能另一个线程正在修改相同的集合,并可能导致ConcurrentModificationException异常。 - Min2

10
 public void DeleteUserIMP(UserIMP useriamp) {
       synchronized (ListUserIMP) {
            if (ListUserIMP.isEmpty()) {
            System.out.println("user is empty");
        }  else {
            Iterator<UserIMP> it = ListUserIMP.iterator();
            while (it.hasNext()) {
                UserIMP user = it.next();
                if (useriamp.getMoblieNumber().equals(user.getMoblieNumber())) {
                    it.remove();
                    System.out.println("remove it");
                }
            }
            // ListUserIMP.remove(useriamp);

            System.out.println(" this user removed");
        }
        Constants.RESULT_FOR_REGISTRATION = Constants.MESSAGE_OK;
        // System.out.println("This user Deleted " + Constants.MESSAGE_OK);

    }
}

7

如前所述

iterator.remove()

在循环过程中删除列表项可能是唯一安全的方法。

如果想更深入地了解使用迭代器删除项目,请尝试查看这个线程


我很惊讶没有赞同,我完全同意你的做法。这是最安全的方式。 - Simmant

4

我假设数组i是升序排列的,这里有另一种使用迭代器的解决方案,更加通用:

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
list.add("G");
list.add("H");

int i[] = {1,3,5};

Iterator<String> itr = list.iterator();
int pos = 0;
int index = 0;
while( itr.hasNext() ){
    itr.next();
    if( pos >= i.length ){
        break;
    }
    if( i[pos] == index ){
        itr.remove();
        pos++;
    }

    index++;
}

3
String[] mString = new String[] {"B", "D", "F"};

for (int j = 0; j < mString.length-1; j++) {
        List_Of_Array.remove(mString[j]);
}

2

arraylist的remove(int index)方法会移除列表中指定位置(index)的元素。在移除arraylist项后,任何后续元素都会向左移动。

这意味着如果一个arraylist包含{20,15,30,40}

我调用了方法:arraylist.remove(1)

那么数据15将被删除,而30和40这两个项目将向左移动1个位置。

因此,您必须先删除arraylist中较高索引的项。

所以...针对您给出的情况...代码将是...

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
list.add("G");
list.add("H");

int i[] = {1,3,5};

for (int j = i.length-1; j >= 0; j--) {
    list.remove(i[j]);
}

2
这个怎么样?只是思考一下 -
import java.util.ArrayList;

class Solution
{
        public static void main (String[] args){

             ArrayList<String> List_Of_Array = new ArrayList<String>();
             List_Of_Array.add("A");
             List_Of_Array.add("B");
             List_Of_Array.add("C");
             List_Of_Array.add("D");
             List_Of_Array.add("E");
             List_Of_Array.add("F");
             List_Of_Array.add("G");
             List_Of_Array.add("H");

             int i[] = {1,3,5};

             for (int j = 0; j < i.length; j++) {
                 List_Of_Array.remove(i[j]-j);
             }

             System.out.println(List_Of_Array);

        }


}

输出结果为-

[A, C, E, G, H]

2

试着这样做:

ArrayList<String> List_Of_Array = new ArrayList<String>();
List_Of_Array.add("A");
List_Of_Array.add("B");
List_Of_Array.add("C");
List_Of_Array.add("D");
List_Of_Array.add("E");
List_Of_Array.add("F");
List_Of_Array.add("G");
List_Of_Array.add("H");

int i[] = {5,3,1};

for (int j = 0; j < i.length; j++) {
    List_Of_Array.remove(i[j]);
}

2

如果你使用"=",第二个数组列表会为原始数组列表创建一个副本,但引用是相同的,所以如果你在一个列表中进行更改,另一个列表也将被修改。使用此方法代替"="。

        List_Of_Array1.addAll(List_Of_Array);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接