Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7006877

(alt-rt coll) TreeMap set view of mappings doesn't support setValue

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 8
    • 7
    • core-libs

      SYNOPSIS
      --------
      (alt-rt) TreeMap set view of mappings doesn't support setValue
      -or-
      Experimental TreeMap implementation does not allow modification via Iterator

      OPERATING SYSTEMS
      -----------------
      All

      FULL JDK VERSION
      ----------------
      1.6.0_14 onwards, with -XX:+AggressiveOpts enabled

      PROBLEM DESCRIPTION from LICENSEE
      ---------------------------------
      An experimental implementation of TreeMap was added in 1.6.0_14:

      http://www.oracle.com/technetwork/java/javase/6u14-137039.html#performance-6u14

      This new implementation is enabled via the command line option -XX:+AggressiveOpts.

      With the standard TreeMap implementation, the value of Map.Entry key/value pairs returned by TreeMap's Iterator can be modified by calling Map.Entry.setValue().

      With the experimental implemention enabled, it is not possible to modify the values in this way. Calls to Map.Entry.setValue() result in an UnsupportedOperationException. This seems to be because the experimental implementation returns an immutable Entry (defined in AbstractMap) - so this behaviour seems to be intentional. However, since the default TreeMap implementation's Iterator returns mutable Map.Entry objects, the change in the experimental TreeMap breaks backward compatibility.

      The situation is made more confusing by the API documentation for TreeMap. The documentation was changed in Java 6, with the addition of the following paragraph:

      "All Map.Entry pairs returned by methods in this class and its views
      represent snapshots of mappings at the time they were produced. They do
      not support the Entry.setValue method. (Note however that it is
      possible to change mappings in the associated map using put.)"

      http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html

      This would represent a significant change in behaviour vs 5.0 - it would would break backwards compatibility, and it is debatable whether a small addition to the API documentation is sufficient to cover/explain it. In addition, the provided testcase demonstrates that it is not even correct - Map.Entry pairs returned by the default TreeMap implementation's Iterator DO support the Entry.setValue method.

      It is also worth noting that the documentation for TreeMap.entrySet(), which returns the Iterator, states the following:

      "Returns a Set view of the mappings contained in this map. The set's
       iterator returns the entries in ascending key order. The set is backed
       by the map, so changes to the map are reflected in the set, and
       vice-versa. If the map is modified while an iteration over the set is
       in progress (except through the iterator's own remove operation, or
       through the setValue operation on a map entry returned by the iterator)
       the results of the iteration are undefined."

       http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html#entrySet%28%29

      Which would suggest that setValue() IS supported, contrary to the new paragraph at the beginning of the TreeMap documentation.

      So, in summary, it's not clear whether this is a bug in the experimental TreeMap implementation, a bug in the default TreeMap implementation, or a documentation bug. This report is being filed to obtain a definitive answer on this subject.

      TESTCASE
      --------
      import java.util.*;

      public class TreeMapTest {
          public static void main(String[] args) {
              TreeMap<String,Integer> map = new TreeMap<String,Integer>();
              map.put("A", 1);
              Iterator iter = map.entrySet().iterator();
              Map.Entry entry = (Map.Entry)iter.next();
              entry.setValue(new Integer(2));
          }
      }

      REPRODUCTION INSTRUCTIONS
      -------------------------
      1. javac TreeMapTest.java
      2. java -XX:+AggressiveOpts TreeMapTest

      Example output:

      Exception in thread "main" java.lang.UnsupportedOperationException
              at java.util.AbstractMap$SimpleImmutableEntry.setValue(AbstractMap.java:726)
              at TreeMapTest.main(TreeMapTest.java:10)

      WORKAROUND
      ----------
      See Workaround section.

            mduigou Mike Duigou
            dkorbel David Korbel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: