我有一个使用Comparable <>定义“自然排序顺序”的对象。这些都存储在TreeSet中。
除了删除和重新添加对象之外,当用于定义排序顺序的成员更新时,还有另一种方法可以更新排序吗?
我有一个使用Comparable <>定义“自然排序顺序”的对象。这些都存储在TreeSet中。
除了删除和重新添加对象之外,当用于定义排序顺序的成员更新时,还有另一种方法可以更新排序吗?
TreeSet
呼叫相对应的GUI update
,或者如果值发生更改,则控制器(观察者模式)将由模型触发
Answers:
正如其他人指出的那样,没有内置方法。但是,您始终可以使用您选择的构造函数将该TreeSet子类化,并添加所需的功能:
public class UpdateableTreeSet<T extends Updateable> extends TreeSet<T> {
// definition of updateable
interface Updateable{ void update(Object value); }
// constructors here
...
// 'update' method; returns false if removal fails or duplicate after update
public boolean update(T e, Object value) {
if (remove(e)) {
e.update(value);
return add(e);
} else {
return false;
}
}
}
从那时起,您将必须调用((UpdateableTreeSet)mySet).update(anElement, aValue)
以更新排序值和排序本身。这确实需要您update()
在数据对象中实现其他方法。
我遇到了类似的问题,找到了这个线程和tucuxi的答案(谢谢!),在此基础上我实现了自己的UpdateableTreeSet
。我的版本提供了
UpdateableTreeSet
向用户隐藏了很多复杂性。除了延迟的批量更新/删除,tucuxi所示的单元素更新/删除在该类中仍然可用。
2012年8月7日更新:该类可在一个小的GitHub存储库中使用,其中包括一个自述性自述文件,其中包含原理图示例代码以及单元测试,这些单元测试显示了(不)更详细地使用它。
Set
我认为,如果您确实需要使用,那么您就不走运了。
不过,我将使用通配符-如果您的情况足够灵活,可以使用aList
代替a Set
,那么您可以使用Collections.sort()
来List
按需重新排序。如果List
不需要太多更改订单,这应该是高性能的。
List
,无法实用。
这有助于了解您的对象将以小增量还是大改变。如果每个更改都很小,那么将数据放在一个保持排序的列表中会非常好。为此,您必须
但是您必须确保没有人不经过“您”就可以更改元素。
编辑:也!Glazed Lists为此提供了一些支持:
当我尝试实现类似于苹果iPhone滚轮的动态滚动窗格时,我查找了此问题。中的项目TreeSet
是此类:
/**
* Data object that contains a {@code DoubleExpression} bound to an item's
* relative distance away from the current {@link ScrollPane#vvalueProperty()} or
* {@link ScrollPane#hvalueProperty()}. Also contains the item index of the
* scrollable content.
*/
private static final class ItemOffset implements Comparable<ItemOffset> {
/**
* Used for floor or ceiling searches into a navigable set. Used to find the
* nearest {@code ItemOffset} to the current vValue or hValue of the scroll
* pane using {@link NavigableSet#ceiling(Object)} or
* {@link NavigableSet#floor(Object)}.
*/
private static final ItemOffset ZERO = new ItemOffset(new SimpleDoubleProperty(0), -1);
/**
* The current offset of this item from the scroll vValue or hValue. This
* offset is transformed into a real pixel length of the item distance from
* the current scroll position.
*/
private final DoubleExpression scrollOffset;
/** The item index in the list of scrollable content. */
private final int index;
ItemOffset(DoubleExpression offset, int index) {
this.scrollOffset = offset;
this.index = index;
}
/** {@inheritDoc} */
@Override
public int compareTo(ItemOffset other) {
double d1 = scrollOffset.get();
double d2 = other.scrollOffset.get();
if (d1 < d2) {
return -1;
}
if (d1 > d2) {
return 1;
}
// Double expression has yet to be bound
// If we don't compare by index we will
// have a lot of values ejected from the
// navigable set since they will be equal.
return Integer.compare(index, other.index);
}
/** {@inheritDoc} */
@Override
public String toString() {
return index + "=" + String.format("%#.4f", scrollOffset.get());
}
}
该DoubleExpression
可采取在JavaFX平台的runLater任务被束缚了一下,这就是为什么该指数包含在该包装类。
由于scrollOffset
始终根据用户在滚轮上的滚动位置而变化,因此我们需要一种更新方法。通常,顺序总是相同的,因为偏移量是相对于商品索引位置的。索引永远不会改变,但是偏移量可以是负值,也可以是正值,具体取决于与当前vValue或hValue属性的相对距离ScrollPane
。
要仅在需要时按需更新,只需遵循Tucuxi对上述答案的指导。
ItemOffset first = verticalOffsets.first();
verticalOffsets.remove(first);
verticalOffsets.add(first);
其中verticalOffsets是一个TreeSet<ItemOffset>
。如果每次调用此更新代码片段时都打印出不符合规定的内容,则会看到它已更新。
我认为没有现成的方法可以做到这一点。
您可以使用观察者模式,该模式在您更改元素内的值时会通知树集,然后将其删除并重新插入。
这样,您可以隐式保持列表的排序,而无需手动进行处理。.当然,此方法将需要TreeSet
通过修改插入行为来扩展(在刚刚添加的项目上设置观察/通知机制)