我有一套,比如说
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]
当我插入多个集合时它会起作用。但是当它们的大小发生变化时,排序的顺序就不会保留。
有没有办法保持集合的大小,但动态排序?
答案 0 :(得分:1)
可以通过仅允许将特殊集合作为TreeBag来获取TreeBag
作为参数,并在Set更改时在Treebag上调用sort方法。我已经尝试了这个并且它有效,但它有很多缺点(只允许特殊的Set,如果一个特殊的Set移动到另一个Treebag,等等),我永远不会在任何通用的代码片段中使用它,只有例外是当代码非常孤立时。
另一种方法是使用Bag
将Bag
的排序责任移到代码中。一个简单的实用方法(易于阅读,易于维护)可以做到这一点:
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());
}
}