【问题标题】:TreeSet or TreeMap auto sort, when the underlying object's field value changes当底层对象的字段值发生变化时,TreeSet 或 TreeMap 自动排序
【发布时间】:2015-11-26 18:43:32
【问题描述】:

是否有任何内置集合,其中对象按排序顺序排序?并且在更改存储对象的字段(用于确定顺序)时,集合将自身重新排列为排序顺序。

集合的底层对象是可变的

请参考以下示例。

 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。

如果没有可用的内置类,请给出一些提示,以便以最小的时间复杂度有效地解决问题。

【问题讨论】:

  • 不,如果您在对象已经在Sorted{Set,Map} 中时对其进行变异,则进入顺序将不会重新排列。无论如何,这基本上是不好的做法。你为什么要那个?你想达到什么目的?
  • @fge 我很少有对象会在某个固定的时间间隔内改变它的状态。我必须让它们在相同的时间间隔后排序。
  • 然后将它们放入List 并在需要时使用Collections.sort()
  • @fge 是的,这肯定会使其排序,但我正在寻找一些更好的方法或算法。我可以实现任何算法。
  • 如你所愿,但为什么不选择一些行之有效的东西呢?

标签: java algorithm sorting binary-search-tree treeset


【解决方案1】:

不存在这样的集合。但是您可以使用观察者模式在集合中的对象发生更改时自动删除/替换它。最好在更新之前将其删除,然后再替换它。

【讨论】:

    【解决方案2】:

    不,您不能只改变地图或集合中的键;这会破坏地图/集合中的未来查找。

    您应该为地图使用不可变的排序键,并且在更新对象时,先从地图中删除项目,然后使用更新的排序键将其放回地图中。

    【讨论】:

      【解决方案3】:

      如果您以改变其字段的方式改变元素,几乎所有Set 的标准实现都将不起作用。例如,HashSet 使用hashCode 将条目放入桶中,因此如果您在将元素放入Set 后对其进行了变异,则将无法再找到它。同样,TreeSet 使用Comparator(通常用于元素的字段)将元素放置在树中,因此您会遇到类似的问题。

      因此,您尝试做的事情将行不通。您可以做的是使用ArrayList 来存储元素,并在需要订单时简单地对List 进行排序。当然,这不会始终保持元素有序。但是,无论如何这是不可能的,因为集合不会收到有关其元素更改的通知。

      【讨论】:

        【解决方案4】:

        您可以从集合中移除对象,修改其值,然后在字段值更改后将其添加回集合中。一旦您添加回对象,树集将再次对其进行排序。在这个用例中,这是我能想到的最好的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          • 2014-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多