Adem Ökmen
Adem Ökmen

Reputation: 326

Iterators in java - remove numbers in a range

I'm trying to remove numbers from a LinkedList using an iterator. I can't get it to remove numbers from only between to variables.

My list contains these values: 1, 1, 2, 0, 4, 5, 6, 8, 8, 3, 11, 9, 12, 0, 14, 0, 16]

The call of the method removeEvenInRange(list,5,13) should remove the even numbers between index 5 and 13, ending up with a list containing [1,1,2,0,4,5,3,11,9,0,14,0,16

I don't know how to "tell" it to only iterate between the indexes 5 - 13. Any help on how to solve this would be much appreciated.

This is what I have so far:

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.ListIterator;

public class Ex11_3_RemoveEvenInRange {

public static void main(String[] args) {

    List<Integer> list = new LinkedList<>();
    list.addAll(Arrays.asList(1,1,2,0,4,5,6,8,8,3,11,9,12,0,14,0,16));

    removeEvenInRange(list, 5, 13);
}

private static void removeEvenInRange(List<Integer> list, int i, int j) {


            Iterator<Integer> itr = list.iterator();

            for (int k = i; k < j; k++) {

                int element = itr.next();

                if (element % 2 == 0) {
                    itr.remove();

                }
            }


                System.out.println(list);

    }
}

Upvotes: 0

Views: 1815

Answers (5)

duckstep
duckstep

Reputation: 1138

You can't, unless you call next() n (5 in this case) times before running your code - which would be insane.

Your best option is probably to split your list into three sublists, iterate over the middle one, and merge the lists after you're done.

Another approach would be using get(index) and remove(index) on the list directly, which saves the split/merge step, but you'll have to make sure you adjust the index for every remove. The split/merge approach is less error-prone.

edit: The Answer by @Masud has example code for this, although it's missing the merge step.

Upvotes: 0

T.Gounelle
T.Gounelle

Reputation: 6033

You will need to count and advance the iterator until you reach the start index. Then you continue counting in parallel of iterating and removing the elements you want to remove through the iterator, until the count reaches the end index.

If you stick to a LinkedList, the above process will be more efficient than removing through the List#remove(index) method (as suggested in some comments), since each call to remove will go through the list to find the index.

Upvotes: 0

BlackBlaze
BlackBlaze

Reputation: 254

If you want use an iterator you can write something like:

 for (int k = 0; k < j; k++) {

         int element = itr.next();
             if (k>=i) {
                    if (element % 2 == 0) {
                        itr.remove();
                       }
                   }

          }

but is more efficient if you use get(int index)

Upvotes: 0

Masudul
Masudul

Reputation: 21971

You can subList between two indexes. Try,

static void removeEvenInRange(List<Integer> list, int i, int j){

    List<Integer> subList= list.subList(i, j);
    Iterator<Integer> itr = subList.iterator();


    while (itr.hasNext()){
        int element = itr.next();
        if (element % 2 == 0) {
            itr.remove();
        }
    }
    System.out.println(list);
}

Upvotes: 4

rgettman
rgettman

Reputation: 178303

What your current implementation is doing is removing all even numbers from the list from index 0 through index j - i - 1, not i through j - 1. The range is shifted because you're not iterating until k is in range.

Start your for loop at index 0, so your index is consistent with the iterator's index. Then add an if statement to determine if your index k is in the proper range between i and j.

for (int k = 0; k < j; k++) {
    int element = itr.next();

    if (k >= i && k < j)
    {
        if (element % 2 == 0) {
            itr.remove();
        }
    }
}

Upvotes: 0

Related Questions