Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TreeMap and setValue method

Tags:

java

In the java.util.TreeMap javadoc there is this statement:

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.)

I don't get this line. In what way they do not support setValue method? When I use entrySet() and iterate over Map.Entry object it sets value fine.

    Map<String, Integer> map = new TreeMap<>();
    map.put("dbc", 1);
    map.put("abc", 1);
    map.put("cbc", 1);
    for(Map.Entry<String, Integer> item: map.entrySet()) {
        item.setValue(1);
    }
like image 955
lapots Avatar asked Nov 30 '14 18:11

lapots


People also ask

What is difference between TreeMap and HashMap?

HashMap allows a single null key and multiple null values. TreeMap does not allow null keys but can have multiple null values. HashMap allows heterogeneous elements because it does not perform sorting on keys. TreeMap allows homogeneous values as a key because of sorting.

What is a TreeMap data structure?

A TreeMap is a memory-efficient data structure which works well with an unknown quantity of data. Find out how to use this class in Java. The Java TreeMap class stores data in a tree structure using a map interface. This class extends the AbstractMap class and, like its parent class, TreeMap has two type parameters.

Why TreeMap is used in Java?

The TreeMap in Java is used to implement Map interface and NavigableMap along with the AbstractMap Class. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

Does TreeMap allow duplicate keys?

A TreeMap cannot contain duplicate keys. TreeMap cannot contain the null key. However, It can have null values.


2 Answers

This is a known issue.

  • There is an OpenJDK tracker entry (JDK-8038146) that notes that this is a javadoc error. But there is more to it than this.

  • There is also a Java Bug Database entry (bug id 7006877) that explains that the javadoc was changed to say that in Java 6, and that it is actually true for the alternative version of TreeMap that you get (got) if you run the JVM with aggressive optimizations enabled.

    This ticket also says that the issue affected Java 7, and was fixed in Java 8. They apparently removed the alternative TreeMap implementation ... though they didn't change the javadoc.


Commentary:

If the issue trackers are to be believed (and I've understood them correctly), then the javadoc probably ought to say that the Entry.setValue method may not be supported in Java 6 and Java 7. But the misleading sentences could be entirely removed for Java 8 onwards.

Whether that is the correct thing to do is somewhat debatable, because some people need to understand how their new Java code might run on older platforms. Maybe it would be best to leave this as a historical footnote.

like image 152
Stephen C Avatar answered Sep 30 '22 21:09

Stephen C


It appears the comment you quoted isn't entirely accurate.

The TreeMap class has a number of methods which return single Map.Entry objects: firstEntry, lastEntry, higherEntry, lowerEntry, etc...

I believe the comment is meant in reference to the methods on TreeMap which return a single Map.Entry. Those methods return a Map.Entry by making an immutable copy of the underlying Entry ( via AbstractMap.SimpleImmutableEntry).

These immutable copies will throw an UnsupportedOperationException if you call their setValue.

After reading the comment you quoted I would have thought that entrySet would return Immutable copies. The javadoc of the TreeMap.entrySet method states:

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. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll and clear operations. It does not support the add or addAll operations.

Given that changes to the Set returned by entrySet must operate on the underlying map I can see why TreeMap doesn't attempt to wrap the Entries - that would severely complicate efforts to keep the Set and the Map in sync.

like image 32
Ryan Avatar answered Sep 30 '22 21:09

Ryan