2017-09-03 93 views
-3

我有这个问题很长一段时间。Java集合框架的内部工作

问题有点长。请耐心等待:)

总之,如何收集数据结构,如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实例P3有 “斑马”名称。即亚当 - >斑马

p3.name = "Zebra"; 

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


QUESTION
在第3节,我修改p3实例来保存 “斑马” 而不是 “亚当”。
问题是,TreeSet如何知道P3实例已被修改?

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

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

+2

你看过源代码吗?它很容易找到 - 是不是你应该首先看的地方? –

+1

我已经运行了你的测试,它不打印亨利。它按照我的预期打印斑马纹。只需运行自己的测试就可以给出答案:它不知道有关更改,在将对象存储在Set中后,更改对象的状态是很重要的。 –

+0

[Stack Overflow用户需要多少研究工作?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users)答案,*“很多,一个荒谬的数额,超过你认为你的能力,当你到达绳索的尽头,并且没有答案的痛苦超过了通过发布你的问题收到的大量耻辱,那就是当你可以继续询问时。“* **看看源代码将花费的时间少于编写这个问题!** –

回答

0

如何收集数据结构,如TreeMap的知道什么时候 底层数据IT卖场被修改,它是如何管理这样的 情况?

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

还要注意TreeSetTreeMap支持,并HashSetHashMap支持,因此与他们同去(与设定值是地图键)。

+0

问题中存在错别字。它的TreeSet不是TreeMap ... – oathkeeper

+2

@oathkeeper TreeSet是一个TreeMap,其中所有条目的值始终是相同的值。 –