Java 列出维护排序的实现
Java中是否有一个现有的Java 列出维护排序的实现,java,list,collections,insertion-order,Java,List,Collections,Insertion Order,Java中是否有一个现有的列表实现,它根据提供的比较器维护顺序 可以用以下方式使用的东西: Comparator<T> cmp = new MyComparator<T>(); List<T> l = new OrderedList<T>(cmp); l.add(someT); 应该通过 欢迎所有建议(除了告诉我在无序的完整列表中使用Collections.sort),不过,我更喜欢java.*或最终org.apache.*,因为目前很难引入新的
列表
实现,它根据提供的比较器
维护顺序
可以用以下方式使用的东西:
Comparator<T> cmp = new MyComparator<T>();
List<T> l = new OrderedList<T>(cmp);
l.add(someT);
应该通过
欢迎所有建议(除了告诉我在无序的完整列表中使用Collections.sort
),不过,我更喜欢java.*
或最终org.apache.*
,因为目前很难引入新的库
注意:(UPDATE4)我意识到这种列表的实现将没有足够的性能。有两种一般方法:
TreeSet
不起作用,因为它使用提供的比较器(MyComparator
)检查相等性,并基于此假设元素相等并排除它们。我只需要那个比较器进行排序,而不是“唯一性”过滤(因为元素按其自然顺序是不相等的)
更新3:
PriorityQueue
不能作为List
(根据需要)工作,因为无法按“排序”的顺序遍历它,要按排序的顺序获取元素,必须将它们从集合中删除
更新:
类似问题:您可能应该使用: 根据使用的构造函数,可以使用元素的自然顺序或在设置的创建时间提供的比较器对元素进行排序 例如:
Comparator<T> cmp = new MyComparator<T>();
TreeSet<T> t = new TreeSet<T>(cmp);
l.add(someT);
Comparator cmp=new MyComparator();
树集=新树集(cmp);
l、 添加(someT);
请注意,这是一个集合,因此不允许重复条目。这可能适用于您的特定用例,也可能不适用于您的特定用例。对新需求的响应。我看到两种潜力:
- 按照JavaDoc for
的说明执行: 此类及其迭代器实现集合和迭代器接口的所有可选方法。方法PriorityQueue
中提供的迭代器不保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用<代码>数组。排序(pq.toAlayle())< /代码>。 鉴于您的要求,我怀疑这将产生最佳性能。如果这是不可接受的,您需要更好地解释您试图实现的目标Iterator()
- 创建一个列表,在添加新元素后对其自身进行排序。这真的很痛苦。。。如果使用链接结构,可以进行有效的插入排序,但局部性不好。如果使用数组支持的结构,则插入排序比较麻烦,但遍历更好。如果迭代/遍历不频繁,则可以保持列表内容不排序,并仅按需排序
- 考虑使用我建议的PriorityQueue,如果需要按顺序进行迭代,请编写一个包装迭代器:
class PqIter implements Iterator<T> { final PriorityQueue<T> pq; public PqIter(PriorityQueue <T> source) { pq = new PriorityQueue(source); } @Override public boolean hasNext() { return pq.peek() != null } @Override public T next() { return pq.poll(); } @Override public void remove() { throw new UnsupportedOperationException(""); } }
SortedSet
时遇到的唯一性/过滤问题。我发现您还需要一个迭代器,所以这不起作用
如果你真正想要的是一个有序的列表,你可以使用一个
Comparator cmp=new MyComparator();
优先级队列pq=新的优先级队列(cmp);
pq.添加(someT);
请注意API文档中关于各种操作的时间属性的说明:
实施说明:此实施为查询和取消查询方法(offer
、poll
、remove()
和add
)提供了O(log(n))时间;删除(对象)
和包含(对象)
方法的线性时间;检索方法的固定时间(peek
、元素
、和大小
)
您还应该注意,PriorityQueue
生成的迭代器的行为与预期不符:
方法Iterator()
中提供的Iterator
不能保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用<代码>数组。排序(pq.toAlayle())< /代码>。
我刚刚注意到番石榴提供了一种营养。此实现是基于数组的,而不是JDK的PriorityQueue
中提供的链接表单,因此可能具有不同的计时行为。如果您正在做一些性能敏感的事情,您可能希望看一看。虽然注释给出的大O时间略有不同(线性和对数),但所有这些时间也应该是有界的,这可能是有用的
本质上没有维护排序的列表
实现,但您可能要寻找的是的实现。A是最常见的。另一个实现是ConcurrentSkipListSet
,用于更具体的用途。请注意,SortedSet
提供了排序功能,但不允许重复输入,列表也不允许重复输入
参考文献:
- 博文
- 那么问题来了
我有一个类似的问题,我正在考虑使用树集。为了避免排除“equal”元素,我将修改比较器,使其不返回0,而是返回(-1,1)之间的随机数,或者始终返回1
如果您无法控制比较器,或者您正在使用比较器执行与插入此解决方案不同的其他操作,则此解决方案对您无效。此行为将违反
列表
合同,通常是一个坏主意。(番石榴已经考虑并拒绝了这些特征。)违反列表
合同的哪一部分?添加(E)
的规范中说“附录
class PqIter implements Iterator<T>
{
final PriorityQueue<T> pq;
public PqIter(PriorityQueue <T> source)
{
pq = new PriorityQueue(source);
}
@Override
public boolean hasNext()
{
return pq.peek() != null
}
@Override
public T next()
{ return pq.poll(); }
@Override
public void remove()
{ throw new UnsupportedOperationException(""); }
}
import com.google.common.collect.TreeMultiset;
public class TreeMultiSetTest {
public static void main(String[] args) {
TreeMultiset<Integer> ts = TreeMultiset.create();
ts.add(1); ts.add(0); ts.add(2);
ts.add(-1); ts.add(5); ts.add(2);
for (Integer i : ts) {
System.out.println(i);
}
}
}
Comparator<T> cmp = new MyComparator<T>();
PriorityQueue<T> pq = new PriorityQueue<T>(cmp);
pq.add(someT);