我注意到,如果稍后更改对象属性值,TreeSet不会按可变对象保持排序顺序.例如,
public class Wrap {
static TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
});
public static void main(String []args){
Student s = new Student(10);
ts.add(s);
ts.add(new Student(50));
ts.add(new Student(30));
ts.add(new Student(15));
System.out.println(ts);
s.age = 24; //Here I change the age of a student in the TreeSet
System.out.println(ts);
}
}
class Student{
int age;
Student(int age){
this.age = age;
}
@Override
public String toString() {
return "Student [age=" + age + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
[Student [age=10], Student [age=15], Student [age=30], Student [age=50]]
[Student [age=24], Student [age=15], Student [age=30], Student [age=50]]
Run Code Online (Sandbox Code Playgroud)
在我更改特定学生的年龄,然后打印TreeSet后,Set似乎不再按排序顺序排列.为什么会这样?以及如何保持它总是排序?
aio*_*obe 12
为什么会这样?
因为该集合无法监视其所有对象的更改......它将如何能够做到这一点?!
出现同样的问题HashSets.HashSet保存对象时,无法更改影响对象哈希码的值.
以及如何保持它总是排序?
您通常从集合中删除元素,修改它,然后重新插入它.换句话说,改变
s.age = 24; //Here I change the age of a student in the TreeSet
Run Code Online (Sandbox Code Playgroud)
至
ts.remove(s);
s.age = 24; //Here I change the age of a student in the TreeSet
ts.add(s);
Run Code Online (Sandbox Code Playgroud)
您还可以使用例如列表,并Collections.sort在每次修改对象时调用列表.
您可以使用观察者模式.让你的TreeSet工具Observer让你Student延伸Observable.您需要做的唯一更改是age通过封装隐藏字段,以便您可以对更改进行更多内部控制.
这是一个启动示例:
public class ObservableTreeSet<O extends Observable> extends TreeSet<O> implements Observer {
public ObservableTreeSet(Comparator<O> comparator) {
super(comparator);
}
@Override
public boolean add(O element) {
element.addObserver(this);
return super.add(element);
}
@Override
@SuppressWarnings("unchecked")
public void update(Observable element, Object arg) {
remove(element);
add((O) element);
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class Student extends Observable {
private int age;
Student(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (this.age != age) {
setChanged();
}
this.age = age;
if (hasChanged()) {
notifyObservers();
}
}
@Override
public String toString() {
return "Student [age=" + age + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
现在做一个new ObservableTreeSet而不是new TreeSet.
static TreeSet<Student> ts = new ObservableTreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
Run Code Online (Sandbox Code Playgroud)
乍一看是丑陋的,但最终主要代码没有变化.只做一个s.setAge(24)和TreeSet意志"重新排序"自己.
| 归档时间: |
|
| 查看次数: |
3869 次 |
| 最近记录: |