java.util.TreeMap行为问题

发布于 2024-09-07 00:09:21 字数 319 浏览 8 评论 0原文

类文档声明 Entry 不能通过 .setValue(...) 修改,但也警告 put(...) 可以工作美好的。

这是否意味着在迭代像 navigableKeySet() 这样的集合视图时 put(...) 会正常工作(即不会导致 ConcurrentModificationException >),只要不进行结构修改(即添加新密钥)?

我正在测试它,但如果我无法打破迭代,我仍然需要一些验证它工作正常(而不是我无法打破它)。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浸婚纱 2024-09-14 00:09:21

TreeMap 的 javadocs 状态:

结构修改是添加或删除一个或多个映射的任何操作;仅仅更改与现有键关联的值并不是结构修改。

因此,可以假设在迭代一组键时更改与给定键关联的值是允许的。

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.

三五鸿雁 2024-09-14 00:09:21

我相信你是对的,只要你不通过添加新键来进行结构修改,你就不会面临 ConcurrentModificationException 的危险。

也就是说,这样的代码在设计上是合法的:

    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}"

我也通过 查看OpenJDK版本的源码,其中modCount++;只执行如果添加了新条目

(在 TreeMap 中,modCount声明为 private transiet,但它的模拟在 AbstractList 被声明为受保护的瞬态,其预期用途是 记录了计算结构修改的数量,以检测 ConcurrentModificationException)。

此外,TreeMap 的文档 明确阐明了什么是结构修改

结构修改是添加或删除一个或多个映射的任何操作;仅仅更改与现有键关联的值并不是结构修改

基于以上所有内容,我会说,是的,不添加新键/值对的 put 不是结构性修改修改,因此不会导致 ConcurrentModificationException

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文