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

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

即:

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

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

您必须使用Iteratorremove函数(不是列表):

 Iterator 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; line是为什么在迭代时使用它时不会抛出exception的原因。

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

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

作为使用迭代器的替代方法,您可以使用Guava集合库。 这具有更多function的优点(如果你涉及到这种事情):

 Predicate hasCurrent = new Predicate() { @Override public boolean apply(Pulse input) { return (input.getCurrent() != null); } }; pulseArray = Lists.newArrayList(Collections2.filter(pulseArray, hasCurrent)); 

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

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

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

 Iterator 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 } } 

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