Wednesday, October 26, 2022

How to Remove Elements From an ArrayList in Java

To remove elements from an ArrayList in Java you have the following options.

  • You can use remove() method provided by ArrayList class to remove an object from ArrayList.
  • You can use remove() method provided by Iterator.
  • There is a removeIf() method too in ArrayList class that can be used Java 8 onwards to remove elements from ArrayList in Java.

In this post we'll see when to use which method and why.


ArrayList remove() method

ArrayList provides two overloaded remove methods for removing element from an ArrayList in Java-

  • remove(int index)- This method takes int (which specifies the index in the list) as parameter and removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices).
  • public boolean remove(Object o)- This method takes the object, which has to be removed as parameter and removes the first occurrence of the specified element from this list, if it is present. If the list does not contain the element, it is unchanged.

If you are just removing an element from an ArrayList without looping the list then you can remove an element by giving its index in the list or specifying the object itself.

import java.util.ArrayList;
import java.util.List;

public class RemoveFromListDemo {
  public static void main(String[] args) {
    List<String> cityList = new ArrayList<String>();
    cityList.add("Delhi");
    cityList.add("Mumbai");
    cityList.add("Kolkata");
    cityList.add("Hyderabad");
    cityList.add("Bangalore");
    cityList.add("Mumbai");
    System.out.println("Original List- " + cityList);
    cityList.remove(1);
    
    cityList.remove("Mumbai");
    System.out.println("List after removing elements- " + cityList);
  }
}

Output

Original List- [Delhi, Mumbai, Kolkata, Hyderabad, Bangalore, Mumbai]
List after removing elements- [Delhi, Kolkata, Hyderabad, Bangalore]

Removing element from ArrayList while iterating the list

Note that using ArrayList's remove method with enhanced for loop or iterator may result in ConcurrentModificationException as the iterators returned by ArrayList class's iterator and ListIterator methods are fail-fast. Which means if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)

Example code

Here is an example where ArrayList's remove() method is used while iterating a list using For-Each loop. As you can see ConcurrentModificationException is thrown.

public class RemoveFromListDemo {
  public static void main(String[] args) {
    List<String> cityList = new ArrayList<String>();
    cityList.add("Delhi");
    cityList.add("Mumbai");
    cityList.add("Kolkata");
    cityList.add("Hyderabad");
    cityList.add("Bangalore");
    cityList.add("Mumbai");
               
    for(String city : cityList){
      if(city.equalsIgnoreCase("Kolkata"))
        cityList.remove(city);
    }
  }
}

Output

Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
 at java.util.ArrayList$Itr.next(Unknown Source)
 at org.netjs.prog.RemoveFromListDemo.main(RemoveFromListDemo.java:20)

Using Iterator's remove method to remove element from ArrayList

While looping if you want to remove any element from an ArrayList you should use use Iterator's remove method so that ConcurrentModificationException is not thrown.

public class RemoveFromListDemo {
  public static void main(String[] args) {
    List<String> cityList = new ArrayList<String>();
    cityList.add("Delhi");
    cityList.add("Mumbai");
    cityList.add("Kolkata");
    cityList.add("Hyderabad");
    cityList.add("Bangalore");
    cityList.add("Mumbai");
                
    Iterator<String> itr = cityList.iterator();
    int i = 0;
    while(itr.hasNext()){
      System.out.println("city " + itr.next());
      if(i == 3 || i == 4){
        itr.remove();
      }
      i++;
    }
    
    System.out.println("After deletion " );
    for(String city : cityList){
      System.out.println("city " + city);
    }
  }
}

Output

city Delhi
city Mumbai
city Kolkata
city Hyderabad
city Bangalore
city Mumbai
After deletion 
city Delhi
city Mumbai
city Kolkata
city Mumbai

Using ArrayList's remove() method with normal for loop

ArrayList's remove method can be used with normal for loop to remove an ArrayList in Java. If index is passed then it may give undesired result because of the fact that all the other elements are shifted to the left when an element is removed.
As example In the given program code if I want to remove the elements at index 3 & 4 then ideally Hyderabad and Bangalore should be removed from the list. Let's see what happens-

public class RemoveFromListDemo {
  public static void main(String[] args) {
    List<String> cityList = new ArrayList<String>();
    cityList.add("Delhi");
    cityList.add("Mumbai");
    cityList.add("Kolkata");
    cityList.add("Hyderabad");
    cityList.add("Bangalore");
    cityList.add("Mumbai");
    
    for(int i = 0; i < cityList.size(); i++){
      if(i == 3 || i == 4){
        cityList.remove(i);
      }
    }
    
    System.out.println("After deletion " );
    for(String city : cityList){
      System.out.println("city " + city);
    }
  }
}

Output

After deletion 
city Delhi
city Mumbai
city Kolkata
city Bangalore

It can be seen that Hyderabad is removed alright but Mumbai is removed instead of Bangalore. This happened because after Hyderabad is removed elements in the list are shifted and Bangalore came in the place of Hyderabad and Mumbai in place of Bangalore. Thus Mumbai was at index 4 hence removed.

In the previous code if we were using city(object) in the if condition then it would have run fine.

public class RemoveFromListDemo {

  public static void main(String[] args) {
    List<String> cityList = new ArrayList<String>();
    cityList.add("Delhi");
    cityList.add("Mumbai");
    cityList.add("Kolkata");
    cityList.add("Hyderabad");
    cityList.add("Bangalore");
    cityList.add("Mumbai");
    
    for(int i = 0; i < cityList.size(); i++){
      String city = cityList.get(i);
      if(city.equalsIgnoreCase("Kolkata") || city.equalsIgnoreCase("Bangalore")){
        cityList.remove(city);
      }
    }    
    System.out.println("After deletion " + cityList);
  }
}

Output

After deletion [Delhi, Mumbai, Hyderabad, Mumbai]

Using removeIf() to remove element from ArrayList

If you are using Java 8, then removeIf() method can be used to remove element from ArrayList, which takes Predicate functional interface as a parameter. In that case we can write the removal code with in one line as-

cityList.removeIf(p -> p.equalsIgnoreCase("Hyderabad") || 
    p.equalsIgnoreCase("Bangalore"));

ArrayList remove method and AutoBoxing problem

While removing elements from an ArrayList of Integers we may get problem because of Autoboxing. As already mentioned there are two overloaded remove methods-

  • Remove(int index)
  • Remove(Object o)

If we give an int as parameter then it will always be treated as a call to remove method with int parameter.
Let's clear it with an example

public class RemoveFromListDemo {
  public static void main(String[] args) {
    
    List<Integer> numberList = new ArrayList<Integer>();
    // adding to list as int, no need to do
    // new Integer(1)
    numberList.add(1);
    numberList.add(2);
    numberList.add(3);
    numberList.add(4);
    
    // Removing by index 1
    numberList.remove(1);
    // This time removing the integer Object 4
    numberList.remove(4);
  }
}

Output

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 3
 at java.util.ArrayList.rangeCheck(Unknown Source)
 at java.util.ArrayList.remove(Unknown Source)
 at org.netjs.prog.RemoveFromListDemo.main(RemoveFromListDemo.java:20)

So, even if a user thinks while removing the second time that he is giving an object as parameter and hoping autoboxing will take care of all the wrapping to Integer Object chore it won't happen in this case. Second call will also be treated as a call to remove method with int parameter. First remove has already removed one element so now the list size is 3 and trying to access index 4 in such a list will throw IndexOutOfBoundsException.

So in this case user has to explicitly tell the compiler that remove method which takes object as parameter has to be called.

numberList.remove(new Integer(4)); 

That's all for this topic How to Remove Elements From an ArrayList in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How ArrayList Works Internally in Java
  2. How to Remove Duplicate Elements From an ArrayList in Java
  3. How to Sort ArrayList in Java
  4. How to Join Lists in Java
  5. Java Collections Interview Questions And Answers

You may also like-

  1. equals() And hashCode() Methods in Java
  2. How HashSet Works Internally in Java
  3. ConcurrentHashMap in Java With Examples
  4. Interface Static Methods in Java 8
  5. Method reference in Java 8
  6. Functional Interfaces in Java
  7. Static Synchronization in Java Multi-Threading
  8. java.lang.ClassCastException - Resolving ClassCastException in Java

No comments:

Post a Comment