如何从ArrayList中删除元素?

时间:2013-11-21 09:15:40

标签: java arraylist

我已将数据添加到ArrayList,现在想要更新该列表,从中删除一些元素。

我的ArrayListCartEntry中有1,2,3,4这样的元素。

代码:

ArrayList<CartEntry> items = new ArrayList<CartEntry>();

public void remove(int pId)
{
    System.out.println(items.size());

    for(CartEntry ce : items)
    {
        if(ce.getpId() == pId)
        {
            items.remove(ce);
            //System.out.println(items.get(1));             
        }
    }   
    items.add(new CartEntry(pId));
}

CartEntry代码:

public long getpId() {
    return pId;
}

构造函数:

public CartEntry(long pId) {
    super();
    this.pId = pId;     
}

当我尝试使用此代码时,它会给我一个错误:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)

这里pId是指定应该从项目中删除项目的参数。 假设我想要删除包含2个数据的项目,那么我将要做什么?

6 个答案:

答案 0 :(得分:14)

您正面临ConcurrentModificationException,因为您一次只对同一list进行两次操作。即循环和删除同一时间。

为了避免这种情况,请使用Iterator,它可以保证您安全地从列表中删除元素。

一个简单的例子看起来像

Iterator<CartEntry> it = list.iterator();
    while (it.hasNext()) {
        if (it.next().getpId() == pId) {
            it.remove();
            break;
        }
    }

答案 1 :(得分:3)

您的代码至少存在两个问题:

  1. 您在迭代的集合上调用remove,如果您继续在remove之后进行迭代,则会产生ConcurrentModificationException

    有两种方法可以解决这个问题:

    • 找到要删除的对象后停止迭代(只需添加breakreturn
    • 从增强型for循环切换为使用an Iteratorits remove method
  2. remove方法中添加元素,这可能不是您想要的。

  3. 所以我使用这段代码(这假设列表中只有一个CartEntry具有给定的ID):

    public void remove(int pId)
    {
        for(CartEntry ce : items)
        {
            if(ce.getpId() == pId)
            {
                items.remove(ce);
                return;
            }
        }   
    }
    

    如果具有唯一ID的假设不正确,那么您需要使用Iterator方法:

    public void remove(int pId)
    {
        Iterator<CartEntry> it = items.iterator();
        while(it.hasNext())
        {
            CartEntry ce = it.next();
            if(ce.getpId() == pId)
            {
                it.remove();
            }
        }   
    }
    

答案 2 :(得分:3)

您已经创建了carEntry类型的Arraylist。因此,您需要创建CarEntry

类型的迭代器
Iterator<CarEntry> it =  items.iterator();    
while(it.hasNext())
{
   if(it.next().getPId == PId)
   it.remove();
}

答案 3 :(得分:1)

在CartEntry中实现.equals然后使用ArrayList.remove(CartEntry)或循环遍历数组列表,找到具有某些条件的项目,标记索引,并调用ArrayList.remove(index) - 循环之后

答案 4 :(得分:1)

尝试,

public void remove(int pId){

Iterator<CartEntry> it = items.iterator();

 while(it.hasNext()) {
    CartEntry entry = it.next();
    if (entry.getpId() == pId) {
        it.remove();
    }
  }
}

答案 5 :(得分:1)

enhanced-for(或每个)循环,用于迭代Expression的子类型Iterable<E>或原始Iterable,基本上等同于以下形式:< / p>

  for (I #i = Expression.iterator(); #i.hasNext(); ) {   
      VariableIdentifiers_opt TargetType Identifier = (TargetType) #i.next();
         Statement
   }

jls 14.14.2. The enhanced for statement部分明确说明了这一点。

对于您的上下文,ExpressionArrayListArrayList的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出ConcurrentModificationException

使用Iterator代替并使用自己的remove()方法:

  Iterator<E>iterator = list.iterator();
  while(iterator.hasNext())
    if(iterator.next().equals(E))
      iterator.remove();