Talha Bin Shakir
Talha Bin Shakir

Reputation: 2561

How do I remove even numbers from an ArrayList?

I have to create a method which has an ArrayList; I need to remove even numbers from this ArrayList. I have written code for that, but there is a logical error which I couldn't identify.

Here is my code:

static void sortList(){

   List <Integer> number=new ArrayList <Integer>();

   number.add(11);
   number.add(45);
   number.add(12);
   number.add(32);
   number.add(36);

   System.out.println("Unsorted List: "+number);
  
   for (int i=0;i<number.size();i++){      
       int even=number.get(i)%2;       
        if (even==0){
            System.out.println("This is Even Number:"+ number.get(i));
            number.remove(i);
        }    
    }

    Collections.sort(number);
    System.out.println("Sorted List: "+number);

 }

The output of the code is:

Unsorted List: [11, 45, 12, 32, 36]
This is Even Number:12
This is Even Number:36
Sorted List: [11, 32, 45]

I am wondering that why 32 is not caught as an even number as it is an even number; I tested then by using different even numbers at same position, but the result is same. Why at index(3), is it happening that any even number couldn't be catch. I am really wondering why. So please any one can help me out for this, and is there any other better way to implement this solution?

Thanks

Upvotes: 0

Views: 36099

Answers (10)

Ravneet Singh
Ravneet Singh

Reputation: 1

You can also add i-- before the loop ends. When we remove an item from list, the next element takes the position of removed item. hence the loop doesn't loops through that element. By decreasing the value of i, the loop goes back and check the item that was skipped earlier.

for (int i=0;i<number.size();i++){      
   int even=number.get(i)%2;       
    if (even==0){
        System.out.println("This is Even Number:"+ number.get(i));
        number.remove(i);
        i--;
    }    
}

Upvotes: 0

Arpit Agrawal
Arpit Agrawal

Reputation: 36

We can use removeIf default method in ArrayList class .

     List <Integer> number=new ArrayList <Integer>();

       number.add(11);
       number.add(45);
       number.add(12);
       number.add(32);
       number.add(36);

       number.removeIf(num -> num%2==0);

       System.out.println(number);

Upvotes: 1

Sudhir Kumar
Sudhir Kumar

Reputation: 1

public class RemoveEvenUsingAL {

    public static void main(String[] args) {
        List<Integer> list= new ArrayList<Integer>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);

        Iterator<Integer> it = list.iterator();
        while(it.hasNext()){
            Integer number= it.next();
            if(number % 2 ==0){
                it.remove();
            }
        }
        System.out.println("ArryList Odd Number="+list);
    }
}

Upvotes: 0

volvox
volvox

Reputation: 1234

What i do (Intelliji with kotlin)

fun main(args: Array<String>) {

 var numbers = arrayList(1,2,3,4,5,6)
 println(numbers.filter{it %2 == 0})

}

result=2,4,6

Upvotes: 0

Walter Mundt
Walter Mundt

Reputation: 25271

Both answers about list indices changing are correct. However, also be aware that removing an item from an ArrayList is slow because it has to actually shuffle all of the following entries down. Instead, I recommend creating a new list containing only the even numbers, and then just throwing away the old list. If you want to use the Iterator-based remove code in the other answer, it will work fine for small results as is, and for larger data sets if you use LinkedList. (I believe that is the name; my Java is admittedly slightly rusty.)

Upvotes: 4

dustmachine
dustmachine

Reputation: 10824

Here's another nifty way of filtering for odd elements. Instead of looping through the collection manually, offload the work to Apache Commons Collections

 // apply a filter to the collection
 CollectionUtils.filter(numbers, new Predicate() {
     public boolean evaluate(Object o) {
         if ((((Integer) o) % 2) == 0) { 
             return false;  // even items don't match the filter
         }
         return true;  // odd items match the filter
     }
 });

It's debatable whether this is actually easier to read and understand, but it's more fun. If a certain kind of Predicate is used frequently, it can be refactored out into a static constant and reused all over the place. This could turn the usage of it into something a lot cleaner:

CollectionUtils.filter(numberList, ODD_PREDICATE);

Upvotes: 0

BalusC
BalusC

Reputation: 1109062

Use an Iterator. It has an remove() method which you need.

List<Integer> numbers = new ArrayList<Integer>();

numbers.add(11);
numbers.add(45);
numbers.add(12);
numbers.add(32);
numbers.add(36);

System.out.println("Unsorted List: " + numbers);

for (Iterator<Integer> iterator = numbers.iterator(); iterator.hasNext();) {
    Integer number = iterator.next();
    if (number % 2 == 0) {
        System.out.println("This is Even Number: " + number);
        iterator.remove();
    }

}

Collections.sort(numbers);
System.out.println("Sorted List: " + numbers);

Upvotes: 6

Stephen
Stephen

Reputation: 3621

The problem (as others have mentioned) is that you are modifying the list while you are traversing it. Try adding a "i--;" line inside your "if (even==0)" block. Like this:

for (int i=0;i<number.size();i++){
    int even=number.get(i)%2;

    if (even==0){
        System.out.println("This is Even Number:"+ number.get(i));
        number.remove(i);

        // Add this:
        i--;
    }
}

Upvotes: 1

Adam Wright
Adam Wright

Reputation: 49386

If you remove an entry from the list whilst looping over it, you'll have to adjust your loop index. Don't forget, removing the element reduces the length of the list by one, and effectively "shuffles back" the index of all elements after it.

Upvotes: 1

Rasmus Kaj
Rasmus Kaj

Reputation: 4360

When you remove something from the list, the indexes of everything after that changes!

Specifically, in your implementation 32 is not removed as it comes directly after another even number.

I would use an Iterator to walk over the list, and the remove operation on that iterator instead, something like this:

for(Iterator i = number.iterator(); i.hasNext(); ) {
    if (isEven(i.next()) {
        i.remove();
    }
}

Upvotes: 8

Related Questions