Remove objects from an ArrayList based on a given

2020-02-05 13:02发布

I would like to remove an element from an ArrayList in Java if it meets a certain criteria.

ie:

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

I can understand why this does not work, but what is a good way to do this?

7条回答
混吃等死
2楼-- · 2020-02-05 13:14

Using an Iterator would give you the power of modifying the list while iterating through the arraylist

查看更多
倾城 Initia
3楼-- · 2020-02-05 13:15

As an alterative to using an iterator, you can use the Guava collections library. This has the advantage of being more functional (if you are into that sort of thing):

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

pulseArray = Lists.newArrayList(Collections2.filter(pulseArray, hasCurrent));
查看更多
▲ chillily
4楼-- · 2020-02-05 13:26

No need to use iterator. With Java 8 (streaming and filtering capability and lambdas) you can accomplish it using one line. For eg. the required code that does the operation you specified will be :

pulseArray = pulseArray.stream().filter(pulse -> pulse != null).collect(Collectors.toList());
查看更多
Summer. ? 凉城
5楼-- · 2020-02-05 13:27

You can use Collection::removeIf(Predicate filter) (available from Java8 onwards), here is a simple example:

final Collection<Integer> list = new ArrayList<>(Arrays.asList(1, 2));
list.removeIf(value -> value < 2);
System.out.println(list); // outputs "[2]"
查看更多
唯我独甜
6楼-- · 2020-02-05 13:27

You can't alter a collection that you're iterating through using methods on the collection. However, some iterators (including iterators on ArrayLists) support a remove() method that allows you to remove methods in the order that you're iterating.

Iterator<Pulse> iterator = pulseArray.iterator();
while (iterator.hasNext()) {
  Pulse p = iterator.next();
  if (p.getCurrent() == null) {
    iterator.remove();
  }
}
查看更多
成全新的幸福
7楼-- · 2020-02-05 13:31

You must use an Iterator to iterate and the remove function of the iterator (not of the list) :

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

Note that the Iterator#remove function is said to be optionnal but it is implemented by the ArrayList's iterator.

Here's the code of this concrete function from 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     }

The expectedModCount = modCount; line is why it won't throw an exception when you use it while iterating.

查看更多
登录 后发表回答