One of the more common tasks in programming is removing a specific element from a list. Although this seems to be straight-forward in Java, it’s a bit more tricky.
Before we start, we should build our list:
public ArrayList<String> createList(){ ArrayList<String> myList = new ArrayList<String>(); myList.add("String 1"); myList.add("String 2"); myList.add("String 3"); myList.add("String 4"); myList.add("String 5"); return myList; }
Let’s say we want to remove the String “String 2”. The first thing that comes to mind is to loop through the list, until you find the element “String 2”, and remove that element:
public List<String> removeFromListUsingForEach(List<String> sourceList){ for(String s : sourceList){ if (s.equals("String 2")){ sourceList.remove(s); } } return sourceList; }
Unfortunately, in this case, this will throw a
java.util.ConcurrentModificationException
I said “in this case”, because the exception is not always thrown. The details of this strange behavior is out of scope for this blogpost, but can be found here.
There are several ways to remove an element from a list. Depending on your personal preference, and which version of Java you use, here are some examples.
1. Use a for-loop which loops backwards
You can use a for-loop, which runs from the end of the list to the beginning. The reason you want to loop in this direction is, that when you’ve found the element you want to remove, you remove the element at that index. Every element after this one will shift one position towards the beginning of the list. If you’d run the loop forward, you’d have to compensate for this, which just isn’t worth the effort.
public List<String> removeFromListUsingReversedForLoop(List<String> sourceList){ for(int i = sourceList.size()-1; i >= 0; i--){ String s = sourceList.get(i); if (s.equals("String 2")){ sourceList.remove(i); } } return sourceList; }
This works in every Java version since 1.2, although you can’t use generics until Java 1.5.
2. Use an Iterator
Another way to remove an element from a list is to use an Iterator. The Iterator will loop through the list, and, if needed, can remove the current element from that list. This is done by calling
Iterator.remove()
public List<String> removeFromListUsingIterator(List<String> sourceList){ Iterator<String> iter = sourceList.iterator(); while (iter.hasNext()){ if (iter.next().equals("String 2")){ iter.remove(); } } return sourceList; }
This works in every Java version since 1.2, although you can’t use generics until Java 1.5.
3. Use Java 8 Streams
What you’re essentially doing here is make a copy of the list, and filter out the unwanted elements.
public List<String> removeFromListUsingStream(List<String> sourceList){ List<String> targetList = sourceList.stream() .filter(s -> !s.equals("String 2")) .collect(Collectors.toList()); return targetList; }
This works since Java 1.8. More about Java 8 can be found here.