TreeSet 或 TreeMap 自动排序,当底层对象的字段值改变时
TreeSet or TreeMap auto sort, when the underlying object's field value changes
是否有任何内置集合,其中对象按排序顺序排序?并且在更改存储对象的字段(用于确定顺序)时,集合将其自身重新排列为排序顺序。
集合的底层对象是可变的。
请参考下面的例子。
Emp implements Comparable<Emp> {
Integer id;
Emp(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public int compareTo(Emp o) {
return this.id.compareTo(o.id);
}
}
Emp e1 = new emp(1);
Emp e2 = new emp(2);
Emp e3 = new emp(3);
Set<Emp> sortedSet = new TreeSet<Emp>();
sortedSet.add(e1);
sortedSet.add(e2);
sortedSet.add(e3);
// till now object is in sorted order
e2.setId(10);
// I need some method of the collection to make it sorted again.
我需要 sortedSet 再次按排序顺序(通过调用某种方法)并且在 e2 更改后顺序为 e1、e3、e2。
如果没有可用的内置 class,请给出一些提示,以最小的时间复杂度有效地解决问题。
不,您不能只改变映射或集合中的键;这会破坏 map/set.
中的未来查找
您应该为地图使用不可变的排序键,并且在更新对象时,先从地图中删除该项目,然后使用更新后的排序键将其放回地图中。
不存在这样的集合。但是你可以使用观察者模式在集合中的对象发生变化时自动 remove/replace 。最好在更新发生之前将其删除,然后再将其替换。
如果您以更改元素字段的方式改变元素,几乎所有 Set
的标准实现都将不起作用。例如,HashSet
使用 hashCode
将条目放入桶中,因此如果您在将元素放入 Set
后对其进行变异,将无法再找到它。类似地,TreeSet
使用 Comparator
(通常在元素的字段上使用)将元素放置在树中,因此您会遇到类似的问题。
所以你尝试做的事情是行不通的。您可以做的是使用 ArrayList
来存储元素,并在需要顺序时简单地对 List
进行排序。当然,这不会始终保持元素有序。但是,无论如何这都是不可能的,因为集合不会收到元素更改的通知。
您可以从集合中删除对象,修改其值,然后在字段值更改后将其添加回集合。一旦您添加回对象,树集将再次对其进行排序。这是我在这个用例中能想到的最好的。
是否有任何内置集合,其中对象按排序顺序排序?并且在更改存储对象的字段(用于确定顺序)时,集合将其自身重新排列为排序顺序。
集合的底层对象是可变的。
请参考下面的例子。
Emp implements Comparable<Emp> {
Integer id;
Emp(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public int compareTo(Emp o) {
return this.id.compareTo(o.id);
}
}
Emp e1 = new emp(1);
Emp e2 = new emp(2);
Emp e3 = new emp(3);
Set<Emp> sortedSet = new TreeSet<Emp>();
sortedSet.add(e1);
sortedSet.add(e2);
sortedSet.add(e3);
// till now object is in sorted order
e2.setId(10);
// I need some method of the collection to make it sorted again.
我需要 sortedSet 再次按排序顺序(通过调用某种方法)并且在 e2 更改后顺序为 e1、e3、e2。
如果没有可用的内置 class,请给出一些提示,以最小的时间复杂度有效地解决问题。
不,您不能只改变映射或集合中的键;这会破坏 map/set.
中的未来查找您应该为地图使用不可变的排序键,并且在更新对象时,先从地图中删除该项目,然后使用更新后的排序键将其放回地图中。
不存在这样的集合。但是你可以使用观察者模式在集合中的对象发生变化时自动 remove/replace 。最好在更新发生之前将其删除,然后再将其替换。
如果您以更改元素字段的方式改变元素,几乎所有 Set
的标准实现都将不起作用。例如,HashSet
使用 hashCode
将条目放入桶中,因此如果您在将元素放入 Set
后对其进行变异,将无法再找到它。类似地,TreeSet
使用 Comparator
(通常在元素的字段上使用)将元素放置在树中,因此您会遇到类似的问题。
所以你尝试做的事情是行不通的。您可以做的是使用 ArrayList
来存储元素,并在需要顺序时简单地对 List
进行排序。当然,这不会始终保持元素有序。但是,无论如何这都是不可能的,因为集合不会收到元素更改的通知。
您可以从集合中删除对象,修改其值,然后在字段值更改后将其添加回集合。一旦您添加回对象,树集将再次对其进行排序。这是我在这个用例中能想到的最好的。