我已经有了一个对象,定义了一个'自然顺序排序'使用可比较<>.这些都被储存在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顺序并没有被多大改变。

它有助于知道无论你的目的将改变小增量或大。如果每一个变化是非常小的,你会做的很好把你的数据在一个列表,继续进行排序。要做到这一点,你必须

  1. binarySearch找到的指标的元素
  2. 修改的元素
  3. 虽然元素是否大于其右手的邻居,与它交换它的右手的邻居
  4. 或者如果没有发生这样的情况:而元件的低于其左邻,与它交换其左邻居。

但你必须确保没有一个能改变元素而不需要通过"你"做到这一点。

编辑: 也!上釉的名单有一些支持只是这样的:

http://publicobject.com/glazedlists/glazedlists-1.5.0/api/ca/odell/glazedlists/ObservableElementList.html

我抬起头时,我试图实现类似苹果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(设置观测/通知对刚刚添加的项目力学)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top