【问题标题】:Internal working of Java Collections Framework [duplicate]Java Collections Framework的内部工作[重复]
【发布时间】:2017-09-03 15:13:04
【问题描述】:

这个问题我已经问了很久了。

问题有点长。请多多包涵:)

总而言之,TreeSet 等集合数据结构如何知道它存储的底层数据何时被修改以及如何管理此类情况??

示例

//Simple person class with name data member
public static class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}


1.创建一个 TreeSet 并添加 3 个 Person 实例 p1、p2、p3。 (比较器排序名称)。

TreeSet<Person> set = new TreeSet<>(new Comparator<Person>() {
    @Override
    public int compare(Person person1, Person person2) {
        return person1.name.compareTo(person2.name);
    }
});

// Creating 3 Person instances and adding to set.
Person p1 = new Person("Zach"),
        p2 = new Person("Henry"),
        p3 = new Person("Adam");

// Adding to set
set.add(p1);  set.add(p2);  set.add(p3);


2.打印第一个元素(打印平衡 BST 中的字典最小字符串)

// This will name of P3 instance, i.e. Adam (obvious and expected) 
System.out.println(set.first().name);
// "Adam" is printed which is expected.


3.将 Person Instance P3 修改为具有“zebra”名称。即亚当 -> 斑马

p3.name = "Zebra";

System.out.println(set.first().name);


问题
在第 3 节中,我修改了p3 实例以包含“Zebra”而不是“Adam”。
问题是,TreeSet怎么知道P3实例被修改了???

TreeSet 是使用一些平衡 BST(通常是 RB 树)构建的。因此,当我更改一些数据时,它必须重新排序树的内部节点以保持遵守比较器的规则。
那么,TreeSet 是如何得到通知底层数据已被修改并且必须再次重新排序树节点的?

我真的很想知道它在内部是如何工作的。是观察者模式吗? 要求详细而全面的答案:)

【问题讨论】:

  • 你看过源代码吗?它很容易获得且易于找到——这不是您应该首先查看的地方吗?
  • 我已经运行了你的测试,它没有打印亨利。正如我所料,它会打印 Zebra。只需运行您自己的测试就会给您答案:它不知道更改,并且在对象存储在 Set 之后更改其状态是一件大事。
  • How much research effort is expected of Stack Overflow users? 答案,“很多。一个荒谬的数量。超过你认为你的能力。在你到达你的绳索的尽头和没有的痛苦之后答案超过了发布您的问题所收到的大量耻辱,那时您可以继续提问。“ 查看源代码比写这个问题花费的时间更少!跨度>
  • 伙计们,我真的很抱歉发布了错误内容的错误问题。我记得测试了类似的代码并发现了类似的异常。放心:下次我会更加小心。感谢您的努力和建议 :) 我应得的反对票,我谦虚地接受它。

标签: java data-structures collections treeset


【解决方案1】:

TreeMap 等集合数据结构如何知道 它存储的基础数据被修改,它如何管理这些 案例?

它没有。对于值无关紧要,但如果您修改键,它可能会破坏整个集合。这就是为什么您应该更喜欢映射的不可变键,或者至少确保它们在用作键后不会被修改。

还要注意TreeSet 由TreeMap 支持,HashSet 由HashMap 支持,因此它们也是如此(设置值是映射键)。

【讨论】:

  • 问题中有错别字。它是 TreeSet 而不是 TreeMap...
  • @oathkeeper a TreeSet 是一个 TreeMap,其中所有条目的值始终是相同的值。
猜你喜欢
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 2020-06-21
相关资源
最近更新 更多