views:

43

answers:

2

The class docs state that Entrys cannot be modified via .setValue(...) but also caveat that put(...) works fine.

Does that mean put(...) will work fine when iterating over the collection views like navigableKeySet() (i.e., not result in a ConcurrentModificationException), as long as no structural modifications (i.e., adding a new key) are made?

I'm in the middle of testing it out, but if I'm unable to break the iteration, I'd still like some verification that it's working fine (instead of me being unable to break it).

+2  A: 

The javadocs for TreeMap state:

A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with an existing key is not a structural modification.

Therefore one can assume that changing the values associated with a given key while iterating over the set of keys is allowed.

matt b
+1 nice and short.
polygenelubricants
+1 and the accept for being the direct-to-the-most-relevant-point answer. @polygenelubricants' is also good for thoroughness.
Carl
+2  A: 

I believe you are right that as long as you're not making structural modification by adding a new key, you're in no danger of ConcurrentModificationException.

That is, code like this is legal by design:

    NavigableMap<Integer,String> nmap =
        new TreeMap<Integer,String>();

    nmap.put(1, "One");
    nmap.put(2, "Two");
    nmap.put(3, "Three");
    nmap.put(4, "Four");
    nmap.put(5, "Five");

    NavigableSet<Integer> nkeys =
        nmap.navigableKeySet().subSet(2, true, 4, true);

    for (Integer key : nkeys) {
        nmap.put(key, "Blah");
    }

    System.out.println(nmap);
    // prints "{1=One, 2=Blah, 3=Blah, 4=Blah, 5=Five}"

I'm backing this up also by looking at the source code of the OpenJDK version, where modCount++; is only executed if a new Entry is added.

(In TreeMap, modCount is declared as private transiet, but its analog in AbstractList is declared protected transient, and there it's intended usage is documented to count the number of structural modification for the purpose of detecting ConcurrentModificationException).

Additionally, the documentation for TreeMap explicitly clarifies what counts as structural modification:

A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with an existing key is not a structural modification

Based on all of the above, I will say that yes, a put that does not add a new key/value pair is not a structural modification, and thus would not cause a ConcurrentModificationException.

polygenelubricants
+1 - those are also the places I checked; just wanted to make sure I didn't miss anything.
Carl