0

let's say we have a a Pencil class which has two attributes like this:

public class Pencil {
    String color;
    int length;

    public Pencil(String c, int sh, int l) {
        this.color = c;
        this.length = l;
    }
    public String getColor() {
        return color;
    }
}

then we put 4 Pencil's object into a Box:

public class Box {

    ArrayList<Pencil> list;
    public Box() {
        list = new ArrayList<Pencil>();
        list.add(new Pencil("blue", 5, 10));
        list.add(new Pencil("black", 5, 10));
        list.add(new Pencil("brown", 5, 10));
        list.add(new Pencil("orange", 5, 10));
    }
}

and then we want to remove one of these objects from the list based of the value of color:

public class TestDrive {
    public static void main(String[] args) {
        Box b = new Box();
        ArrayList box = b.list;        
        Iterator it = box.iterator();
        while(it.hasNext()) {
            Pencil p = (Pencil) it.next();
            if (p.getColor() == "black") {
                box.remove(p);
            }
        }
    }
}

seems pretty straightforward, but i'm getting Exception in thread "main" java.util.ConcurrentModificationException. I'd appreciate it if someone could tell what I'm missing here

Yar
  • 7,020
  • 11
  • 49
  • 69
  • There's a few issues here...and to ward off any potential dupe-closers, it doesn't feel like it fits neatly into the "compare strings" or "concurrent modification" questions. – Makoto Nov 20 '14 at 03:32
  • Look at this: http://stackoverflow.com/questions/8189466/java-util-concurrentmodificationexception – Marshall Tigerus Nov 20 '14 at 03:32
  • @chrylis: The question being posed in the linked duplicate is of a different nature than the one being posed here. I don't feel that this is a duplicate question. – Makoto Nov 20 '14 at 03:40
  • @Makoto: Disagree. It's about the CME coming from using `box.remove()` in the `while` loop. – chrylis -cautiouslyoptimistic- Nov 20 '14 at 04:51
  • @chrylis Take another look; the question asks why do you get a CME in one instance but not another. This one asks about the CME in one context alone (and there are other issues). It's not a clean duplicate. – Makoto Nov 20 '14 at 04:52

2 Answers2

3

You've got two issues.

The first issue - why you're getting ConcurrentModificationException - is because you're using the list to remove elements, not the iterator.

You must use it.remove() to remove the element you're currently on.

Next, you're comparing strings with == - this isn't guaranteed to work at all. You should be using .equals instead.

Reverse the order you compare them against so you don't run a chance of getting a NullPointerException there, too.

Here's what the block looks like, revisited.

public static void main(String[] args) {
    Box b = new Box();
    ArrayList<Pencil> box = b.list;
    for(Iterator<Pencil> it = box.iterator(); it.hasNext();) {
        Pencil p = it.next();
        if ("black".equals(p.getColor())) {
            it.remove();
        }
    }
}
Makoto
  • 104,088
  • 27
  • 192
  • 230
2

Call it.remove() instead of box.remove(p).

mdnghtblue
  • 1,117
  • 8
  • 27