manis
manis

Reputation: 729

Removing matching elements of a TreeSet

I am trying to remove all numbers that is divisible with some index in a TreeSet and I am using the following code

    TreeSet<Integer> primes = new TreeSet();
    Iterator<Integer> iter = primes.iterator();

    int n = 100;            
    for (int i = n; i > 1; i--){
        primes.add(i);
    }

    for (int i = 2; i < Math.sqrt(n); i ++){
        while (iter.hasNext()){
            int next = iter.next();
            if (next % i == 0){
                primes.remove(next);
            }
        }
    }
    System.out.println(primes);

But for some reason, no elements in the set gets removed

Upvotes: 3

Views: 5033

Answers (6)

S.Yavari
S.Yavari

Reputation: 876

Use the following code:

TreeSet<Integer> primes = new TreeSet();

int n = 100;
for (int i = n; i > 1; i--){
    primes.add(i);
}

Iterator<Integer> iter = primes.iterator();

for (int i = 2; i < Math.sqrt(n); i ++){
    while (iter.hasNext()){
        int next = iter.next();
        if (next % i == 0){
            iter.remove();
        }
    }
}

System.out.println(primes);

Upvotes: 0

Ren&#233; Link
Ren&#233; Link

Reputation: 51393

First create the Iterator after you added the primes and then use Iterator.remove() to not get a ConcurrentModificationException.

TreeSet<Integer> primes = new TreeSet();

    int n = 100;
    for (int i = n; i > 1; i--) {
        primes.add(i);
    }
    Iterator<Integer> iter = primes.iterator();

    for (int i = 2; i < Math.sqrt(n); i++) {
        while (iter.hasNext()) {
            int next = iter.next();
            if (next % i == 0) {
                iter.remove();
            }
        }
    }
    System.out.println(primes);

Upvotes: 2

pratim_b
pratim_b

Reputation: 1200

Iterator.remove() is the only safe way to modify a collection during iteration. Use iter.remove();

  while (iter.hasNext()){
        int next = iter.next();
        if (next % i == 0){
            iter.remove();
        }
    }

Removes from the underlying collection the last element returned by the iterator (optional operation). This method can be called only once per call to next. The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. From ITERATOR

Upvotes: 2

Pieter
Pieter

Reputation: 903

You should get your iterator after adding the elements to the set, and remove from the Iterator to avoid ConcurrentModificationException:

    TreeSet<Integer> primes = new TreeSet<Integer>();

    int n = 100;
    for (int i = n; i > 1; i--) {
        primes.add(i);
    }

    Iterator<Integer> iter = primes.iterator();

    for (int i = 2; i < Math.sqrt(n); i++) {
        while (iter.hasNext()) {
            int next = iter.next();
            if (next % i == 0) {
                // primes.remove(next); // concurrent modification exception!
                iter.remove();
            }
        }
    }
    System.out.println(primes);

Upvotes: 0

thiyaga
thiyaga

Reputation: 251

I think you should end up with concurrent modification exception. You are iterating a treeset using an iterator but at the same time using a remove on the treeset. Please use iter.remove() to remove the element from treeset.

Upvotes: 0

Adam Arold
Adam Arold

Reputation: 30538

You have to use iter.remove() otherwise you'll get ConcurrentModificationExceptions.

In your code you are using primes.remove(next);

Change it to iter.remove() which will remove the current next element.

Upvotes: 0

Related Questions