当底层对象的字段值更改时,TreeSet或TreeMap自动排序

时间:2015-11-26 18:43:33

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

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

该集合的基础对象是可变

请参阅以下示例。

 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.

我需要sortSet再次按排序顺序(通过调用某个方法),并且在e2中更改后的顺序为e1,e3,e2。

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

4 个答案:

答案 0 :(得分:3)

不存在此类收藏。但是,您可以使用Observer模式在更改时自动删除/替换集合中的对象。最好在更新发生之前将其删除,然后将其替换。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

如果以改变字段的方式改变元素,则<div class="wrapper"> <img class="image" src="http://i.stack.imgur.com/NSX3P.png"/> </div>的几乎所有标准实现都不会起作用。例如,Set使用HashSet将条目放入存储桶中,因此如果在将元素放入hashCode后对其进行变更,则无法再找到该元素。同样,Set使用TreeSet(通常在元素的字段上使用)将元素放在树中,因此您会遇到类似的问题。

所以你要做的事情是行不通的。您可以做的是使用Comparator存储元素,只需在需要订单时对ArrayList进行排序。当然,这不会始终保持元素的顺序。但是,这无论如何都是不可能的,因为集合没有被告知其元素的变化。

答案 3 :(得分:-1)

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