根据给定条件从ArrayList中删除对象

问题描述 投票:9回答:7

如果它符合某个标准,我想从Java中的ArrayList中删除一个元素。

即:

for (Pulse p : pulseArray) {
    if (p.getCurrent() == null) {
        pulseArray.remove(p);
    }
}

我可以理解为什么这不起作用,但是这样做的好方法是什么?

java arraylist
7个回答
16
投票

你必须使用Iterator迭代和迭代器的remove函数(不是列表):

Iterator<Pulse> iter = pulseArray.iterator();
while (iter.hasNext()) {
  Pulse p = iter.next();
  if (p.getCurrent()==null) iter.remove();
}

请注意,Iterator#remove函数被称为optionnal,但它由ArrayList迭代器实现。

这是ArrayList.java中这个具体函数的代码:

765         public void remove() {
766             if (lastRet < 0)
767                 throw new IllegalStateException();
768             checkForComodification();
769 
770             try {
771                 ArrayList.this.remove(lastRet);
772                 cursor = lastRet;
773                 lastRet = -1;
774                 expectedModCount = modCount;
775             } catch (IndexOutOfBoundsException ex) {
776                 throw new ConcurrentModificationException();
777             }
778         }
779 
780         final void checkForComodification() {
781             if (modCount != expectedModCount)
782                 throw new ConcurrentModificationException();
783         }
784     }

expectedModCount = modCount;行是在迭代时使用它时不会抛出异常的原因。


13
投票

你可以使用Collection::removeIf(Predicate filter),这是一个简单的例子:

final Collection<Integer> list = new ArrayList<>(Arrays.asList(1, 2));
list.removeIf(value -> value < 2);
System.out.println(list); // outputs "[2]"

3
投票

无需使用迭代器。使用Java 8(流式传输和过滤功能以及lambdas),您可以使用一行完成它。例如。执行您指定的操作所需的代码将是:

pulseArray = pulseArray.stream().filter(pulse -> pulse != null).collect(Collectors.toList());

2
投票

作为使用迭代器的替代方法,您可以使用Guava集合库。这有更多functional的优势(如果你是这样的事情):

Predicate<Pulse> hasCurrent = new Predicate<Pulse>() {
  @Override public boolean apply(Pulse input) {
    return (input.getCurrent() != null);
  }
};

pulseArray = Lists.newArrayList(Collections2.filter(pulseArray, hasCurrent));

0
投票

您无法使用集合上的方法更改正在迭代的集合。但是,一些迭代器(包括ArrayLists上的迭代器)支持remove()方法,该方法允许您按照迭代的顺序删除方法。

Iterator<Pulse> iterator = pulseArray.iterator();
while (iterator.hasNext()) {
  Pulse p = iterator.next();
  if (p.getCurrent() == null) {
    iterator.remove();
  }
}

0
投票

从同一列表中删除元素时,索引会受到干扰。尝试与以下几点不同:

  for (int i=0; i < pulseArray.size(); i++) {
     Pulse p = (Pulse)pulseArray.get(i);
     if (p.getCurrent() == null) {
        pulseArray.remove(p);
        i--;//decrease the counter by one
     }
  }

-1
投票

使用迭代器可以让您在迭代arraylist时修改列表

© www.soinside.com 2019 - 2024. All rights reserved.