Delete objects from ArrayList based on the specified criteria

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

t

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

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

+12
source share
7 answers

You should use an Iterator to iterate and remove an iterator (not a list) function:

 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 called optional, but it is implemented by the ArrayList iterator.

Here is the code for this particular 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 } 

String expectedModCount = modCount; - this is why it will not throw an exception when you use it during iteration.

+19
source

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]" 
+18
source

No need to use an iterator. With Java 8 (streaming and filtering and lambda) you can execute it using a single line. E.g. the required code that performs the operation you specified will be:

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

When you remove an item from the same list , the index becomes violated. Try a little different, as shown below:

  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 } } 
+2
source

As an alternative to using an iterator, you can use the Guava collection library. This has the advantage of being more functional (if you are involved in this):

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

You cannot change the collection that you are repeating using the methods in the collection. However, some iterators (including iterators on ArrayList s) support the remove() method, which allows you to remove methods in the order in which you iterate.

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

Using Iterator will give you the ability to change the list when iterating through arraylist

-one
source

All Articles