Java中的动态排序包集

时间:2014-05-16 18:11:23

标签: java sorting dynamic

我有一套,比如说

Bag<Set<Integer>> sets

我想写一个自定义比较器来按照它们的大小后代对集合进行排序,如下所示:

class SetComparator implements Comparator<Set<Integer>>
{

    @Override
    public int compare(Set<Integer> i, Set<Integer> j) 
    {
        return j.size() - i.size();
    }

}

当我写

Bag<Set<Integer>> sets = new TreeBag<>(new SetComparator());
Set<Integer> s1 = new HashSet<>();
s1.add(3);
s1.add(4);
s1.add(7);
sets.add(s1);
Set<Integer> s2 = new HashSet<>();
s2.add(1);
s2.add(9);
s2.add(12);
s2.add(29);
sets.add(s2); // the order is [s2, s1]
s1.add(5);
s1.add(12); // the order is still [s2, s1]

当我插入多个集合时它会起作用。但是当它们的大小发生变化时,排序的顺序就不会保留。

有没有办法保持集合的大小,但动态排序?

1 个答案:

答案 0 :(得分:1)

可以通过仅允许将特殊集合作为TreeBag来获取TreeBag作为参数,并在Set更改时在Treebag上调用sort方法。我已经尝试了这个并且它有效,但它有很多缺点(只允许特殊的Set,如果一个特殊的Set移动到另一个Treebag,等等),我永远不会在任何通用的代码片段中使用它,只有例外是当代码非常孤立时。

另一种方法是使用BagBag的排序责任移到代码中。一个简单的实用方法(易于阅读,易于维护)可以做到这一点:

public class Bag<T> extends HashSet<Set<T>> {

public Bag() {
    super();
}

public List<Set<T>> sorted() {
    return sorted(new SetComparator<T>());
}

public List<Set<T>> sorted(Comparator<Set<T>> comparator) {

    ArrayList<Set<T>> l = new ArrayList<Set<T>>();
    l.addAll(this);
    Collections.sort(l, comparator);
    return l;
}

static class SetComparator<T> implements Comparator<Set<T>> {

    @Override
    public int compare(Set<T> i, Set<T> j) {
        return j.size() - i.size();
    }
}

public static void main(String[] args) {

    Bag<Integer> b = new Bag<Integer>();
    Set<Integer> s1 = new HashSet<Integer>();
    b.add(s1);
    s1.add(10);
    s1.add(11);
    Set<Integer> s2 = new HashSet<Integer>();
    b.add(s2);
    s2.add(20);
    System.out.println(b.sorted());
    s2.add(21);
    s2.add(22);
    System.out.println(b.sorted());
}
}