维持TreeSet类为对象的变化价值
-
24-09-2019 - |
题
我已经有了一个对象,定义了一个'自然顺序排序'使用可比较<>.这些都被储存在TreeSets.
除去和重新添加的目的,是否有另一种方式来更新排序成员时使用的定义的排列顺序是更新?
解决方案
正如其他人所指出的,没有内置方式。但你总是可以子类,TreeSet中,与您所选择的构造器(S),并添加所需的功能:
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-08-07:本类中提供一点点 库。 其中包括一个介绍自述用意的代码样本以及单元的测试显示如何(不)使用它更详细的说明。
如果你真的需要使用Set
,那么你的运气了,我想。
我要去一个通配符扔,虽然 - 如果您的情况是足够灵活的工作有List
代替Set
,那么你可以使用Collections.sort()
重新排序List
需求。这应该是高性能,如果List
顺序并没有被多大改变。
它有助于知道无论你的目的将改变小增量或大。如果每一个变化是非常小的,你会做的很好把你的数据在一个列表,继续进行排序。要做到这一点,你必须
- binarySearch找到的指标的元素
- 修改的元素
- 虽然元素是否大于其右手的邻居,与它交换它的右手的邻居
- 或者如果没有发生这样的情况:而元件的低于其左邻,与它交换其左邻居。
但你必须确保没有一个能改变元素而不需要通过"你"做到这一点。
编辑: 也!上釉的名单有一些支持只是这样的:
我抬起头时,我试图实现类似苹果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
总是变化基于用户滚动的滚轮的位置,我们需要一种方法来更新。通常的顺序始终是相同的,因为偏移量是相对于所述项目的索引位置。该指数永远不会改变的,但该偏移可能是依赖于物品从ScrollPane
的当前VVALUE或hValue属性相对距离的负或正。
要更新的上仅在需要时按需下,简单地通过南美长吻海豚按照上述答案的指导。
ItemOffset first = verticalOffsets.first();
verticalOffsets.remove(first);
verticalOffsets.add(first);
,其中 verticalOffsets 是一个TreeSet<ItemOffset>
。如果你打印出来的
每本次更新片段被调用的时候设置,你会看到它的更新。
只有内置的方式是删除并重新添加。
我不认为有外的现成的方式来做到这一点。
您可以使用一个的观察者模式强>通知每当改变元素内的值的TreeSet中,然后将其移除并重新插入它。
在这种方式,你可以暗中保存列表排序,而无需手动做..当然,此方法的爱心都需要通过修改插入的行为,延长TreeSet
(设置观测/通知对刚刚添加的项目力学)