Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 列出维护排序的实现_Java_List_Collections_Insertion Order - Fatal编程技术网

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.*,因为目前很难引入新的

Java中是否有一个现有的
列表
实现,它根据提供的
比较器
维护顺序

可以用以下方式使用的东西:

Comparator<T> cmp = new MyComparator<T>();
List<T> l = new OrderedList<T>(cmp);
l.add(someT);
应该通过

欢迎所有建议(除了告诉我在无序的完整列表中使用
Collections.sort
),不过,我更喜欢
java.*
或最终
org.apache.*
,因为目前很难引入新的库

注意:(UPDATE4)我意识到这种列表的实现将没有足够的性能。有两种一般方法:

  • 使用链接结构(排序)B树或类似结构
  • 使用数组和插入(使用二进制搜索)
  • 第一。存在CPU缓存未命中问题 二号。数组中的元素移位有问题

    更新2:
    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
      的说明执行:

      此类及其迭代器实现集合和迭代器接口的所有可选方法。方法
      Iterator()
      中提供的迭代器不保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用<代码>数组。排序(pq.toAlayle())< /代码>。 鉴于您的要求,我怀疑这将产生最佳性能。如果这是不可接受的,您需要更好地解释您试图实现的目标

    • 创建一个列表,在添加新元素后对其自身进行排序。这真的很痛苦。。。如果使用链接结构,可以进行有效的插入排序,但局部性不好。如果使用数组支持的结构,则插入排序比较麻烦,但遍历更好。如果迭代/遍历不频繁,则可以保持列表内容不排序,并仅按需排序

    • 考虑使用我建议的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);