如果符合特定条件,我想从Java中的ArrayList
中删除元素。根据给定的条件从ArrayList中删除对象
即:
for (Pulse p : pulseArray) {
if (p.getCurrent() == null) {
pulseArray.remove(p);
}
}
我能理解为什么这是不行的,但什么是做到这一点的好办法?
如果符合特定条件,我想从Java中的ArrayList
中删除元素。根据给定的条件从ArrayList中删除对象
即:
for (Pulse p : pulseArray) {
if (p.getCurrent() == null) {
pulseArray.remove(p);
}
}
我能理解为什么这是不行的,但什么是做到这一点的好办法?
您必须使用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;
线就是为什么当你使用它,而迭代也不会抛出异常。
从技术上讲,增强型for循环_is_使用迭代器。你能举一个他必须做的例子吗?另外,应该注意的是并不是所有的迭代器都会实际实现remove方法,并且会抛出一个'not implemented'异常。 –
@ Clockwork-Muse是的,但内部ArrayList的迭代器确实实现了它。 –
您无法通过使用集合上的方法来更改要迭代的集合。但是,一些迭代器(包括ArrayList
上的迭代器)支持remove()
方法,该方法允许您按照迭代的顺序删除方法。
Iterator<Pulse> iterator = pulseArray.iterator();
while (iterator.hasNext()) {
Pulse p = iterator.next();
if (p.getCurrent() == null) {
iterator.remove();
}
}
当你从同一列表删除元素,指数受到干扰。尽量少如下不同:
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
}
}
使用迭代器会给你修改的列表,同时通过数组列表
迭代作为备选使用迭代器,你可以使用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));
您可以使用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]"
这适用于我 –
这不仅无法工作,但即使没有工作它会有糟糕的表现。这是一个O(n^2)算法,因为您必须检查阵列中的每个元素,直到您要删除的元素为止。最优算法是O(n)。 –
@MarkByers“检查数组中的每个元素”是O(n),为什么你认为这是O(n^2)? – jlordo
@jlordo:'list.remove(object)'是一个O(n)操作。它被执行O(n)次,因为它在一个循环中。这给出了O(n * n)。 –