TreeMap和setValue方法

时间:2014-11-30 18:01:26

标签: java

java.util.TreeMap javadoc中有这样的陈述:

  

此类中的方法返回的所有Map.Entry对及其视图表示生成时映射的快照。它们不支持Entry.setValue方法。 (但请注意,可以使用put更改关联映射中的映射。)

我不明白这一行。 他们以何种方式不支持setValue方法?当我使用entrySet()并迭代Map.Entry对象时,它会设置正确的值。

    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);
    }

2 个答案:

答案 0 :(得分:7)

这是一个已知问题。

  • 有一个OpenJDK跟踪器条目(JDK-8038146),它指出这是一个javadoc错误。但除此之外还有更多内容。

  • 还有一个Java Bug数据库条目(bug id 7006877),它解释了在Java 6中更改了javadoc,并且实际上是如果您在启用了积极优化的情况下运行JVM,那么您将获得TreeMap的替代版本。

    此票证还说明该问题影响了Java 7,并在Java 8中修复了。他们显然删除了替代TreeMap实现......虽然它们没有更改javadoc。


评论:

如果要相信问题跟踪器(并且我已经正确理解它们),那么javadoc可能应该说Java 6和Java中支持的Entry.setValue方法可能不强但是,对于Java 8以上,可以完全删除误导性的句子

这是否是正确的做法是有争议的,因为有些人需要了解他们的新Java代码如何在旧平台上运行。也许最好把它留作历史脚注。

答案 1 :(得分:1)

您引用的评论似乎并不完全准确。

TreeMap类有许多返回单个Map.Entry对象的方法:firstEntrylastEntryhigherEntrylowerEntry等......

我认为注释是指在TreeMap上返回单个Map.Entry的方法。这些方法通过创建底层Entry的不可变副本(通过AbstractMap.SimpleImmutableEntry)返回Map.Entry。

如果调用setValue,这些不可变副本将抛出UnsupportedOperationException。

在阅读你引用的评论之后,我会认为entrySet会返回Immutable副本。 javadoc of the TreeMap.entrySet method州:

  

返回此映射中包含的映射的Set视图。 set的迭代器以升序键顺序返回条目。该集由地图支持,因此对地图的更改将反映在集中,反之亦然。如果在对集合进行迭代时修改了映射(除非通过迭代器自己的删除操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的。该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从地图中删除相应的映射。它不支持add或addAll操作。

鉴于对entrySet返回的Set的更改必须在底层映射上运行,我可以看到为什么TreeMap不会尝试包装条目 - 这会使Set和Map保持同步的工作变得非常复杂。 / p>