在Java语言中,您可以使用项构建ArrayList
,然后调用:
Collections.sort(list, comparator);
有没有办法在列表创建时传入比较器,就像你可以用TreeMap
做的那样?
目标是能够将元素添加到列表中,而不是自动将其附加到列表的末尾,列表将根据Comparator
保持自身排序,并在由Comparator
确定的索引处插入新元素。因此,基本上列表可能需要对添加的每个新元素进行重新排序。
有没有办法通过Comparator
或其他类似的方法来实现这一点?
发布于 2011-02-05 06:41:52
您可以更改ArrayList的行为
List<MyType> list = new ArrayList<MyType>() {
public boolean add(MyType mt) {
super.add(mt);
Collections.sort(list, comparator);
return true;
}
};
注意: PriorityQueue不是List,如果您不关心它是什么类型的集合,最简单的方法就是使用TreeSet,它与TreeMap类似,但它是一个集合。PriorityQueue的唯一优势是允许重复。
注意:对于大型集合,重新排序的效率不是很高,使用二进制搜索并插入条目会更快。(但更复杂)
编辑:很大程度上取决于你需要“列表”做什么。我建议您为ArrayList、LinkedList、PriorityQueue、TreeSet或其他排序集合编写一个列表包装器,并实现实际使用的方法。这样,您就可以很好地理解集合的要求,并确保它对您来说是正确的。
编辑(2):因为有如此多的人对使用binarySearch感兴趣。;)
List<MyType> list = new ArrayList<MyType>() {
public boolean add(MyType mt) {
int index = Collections.binarySearch(this, mt);
if (index < 0) index = ~index;
super.add(index, mt);
return true;
}
};
发布于 2011-02-05 07:06:09
像TreeSet (或者TreeMultiset,如果你需要重复的话)有更有效的随机访问是可能的,但我怀疑它是用Java语言实现的。让树的每个节点记住它的左子树的大小,可以在time O(log(size))
中按索引访问元素,这是不错的。
为了实现它,您需要重写底层TreeMap的一大部分。
发布于 2011-02-05 07:40:33
我会使用Guava TreeMultiset,假设你想要一个List
,因为你可能有重复的元素。它会做你想做的一切。它不会有一件事是基于索引的访问,这没有多大意义,因为您无论如何都不会将元素放在您选择的索引中。另一件需要注意的事情是,它实际上不会存储equal
对象的副本……只是它们的总数的一个计数。
https://stackoverflow.com/questions/4903611
复制相似问题