【问题标题】:Is there an indexable sorted list in the Java.util package?Java.util 包中是否有可索引的排序列表?
【发布时间】:2011-05-14 00:59:17
【问题描述】:

我正在寻找 java.util 包中的数据结构。我需要它满足以下要求:

  • 元素的数量(理论上)是无限的。
  • 元素按升序排序。
  • 您可以获得第 n 个元素(快速)。
  • 您可以删除第 n 个元素(快速)。

我希望找到一个可索引的跳过列表,但我没有。他们是否有任何符合我所说的要求的数据结构?

【问题讨论】:

  • @Michael:谢谢。我的意思是有序列表。已更正。

标签: java data-structures collections sortedlist


【解决方案1】:

PriorityQueue

如果您的数据结构中不需要类似的元素,那么通常的 TreeSet 也符合您的要求。

【讨论】:

  • 我无法获取/删除优先级队列中的第 n 个元素。只有第一个元素
【解决方案2】:

TreeSet 为您提供自然排序的功能,同时将元素添加到列表中。 但是如果你不需要这个并且 Collections.sort() 是允许的,你可以使用简单的ArrayList

【讨论】:

  • ArrayList - 元素没有排序。 TreeSet - 无法获取/删除第 n 个元素(如果我有键,则只能获取/删除一个元素)
  • 是的,我知道,但它可以排序,例如,如果集合在某个时刻已满且不再更新。
【解决方案3】:

这个问题很像

看看my answer to that question

基本上它建议如下:

class SortedArrayList<T> extends ArrayList<T> {

    @SuppressWarnings("unchecked")
    public void insertSorted(T value) {
        add(value);
        Comparable<T> cmp = (Comparable<T>) value;
        for (int i = size()-1; i > 0 && cmp.compareTo(get(i-1)) < 0; i--) {
            T tmp = get(i);
            set(i, get(i-1));
            set(i-1, tmp);
        }
    }
}

关于您的第一个要求的注释:“元素的数量是无限的。”:

您可能希望将其限制为“元素的数量不应小于 231-1...”,否则您将排除所有选项由 Java 数组支持。 (您可以使用例如 LinkedList 来处理任意数量的元素,但我看不出如何在其中进行快速查找。)

【讨论】:

  • 扩展特定的集合实现很少是一个好主意。尤其是当您尝试执行新合同时(在您的情况下,添加方法可能会破坏排序)。查看Properties 类,了解该做什么!
  • 从 ArrayList 中删除是一个 O(n) 操作。我没有更好的想法,但认为应该指出这一点。
  • @barjak,这是一个很好的观点。例如,可以重写这些方法并抛出 UnsupportedOperationException。尽管如此,我还是不明白为什么仅仅因为这个而从头开始实现 List 接口会更好......
  • @user852631,好点。还应该注意的是,insertSorted 也在 O(n) 中,而它可能可以通过使用不同的数据结构在 O(log n) 中实现。
  • 因为没有理由绑定到ArrayList。例如,如果您想要一个具有“迭代器永不失败”属性的SortedList,那么您的解决方案就不能被重用。您必须重做相同的工作,但这次扩展 CopyOnWriteArrayList 而不是 ArrayList。如果您在这里使用组合而不是继承,那么您可以使用您想要的任何实现后端(例如,在实例化时)。这是Properties 类的错误:它扩展了几乎被弃用的Hashtable 类,这个事实不能再改变了。
【解决方案4】:

考虑将ListCollections.sort() 结合使用。

【讨论】:

  • List只是一个接口,提出一个实现。
【解决方案5】:

不存在满足所有条件的简单数据结构。

据我所知,唯一能满足所有要求的是indexable skip list。但是,我不知道任何现成的 Java 实现。

【讨论】:

  • 另一种数据结构是可索引的搜索树。一个简单的例子是一个二叉搜索树,它也存储了每个节点的子树的大小。
【解决方案6】:

根据 dwb 对List&lt;T&gt;Collections.sort() 的声明,您可以使用ArrayList&lt;T&gt;,因为它实现了List&lt;T&gt;(并且不像Vector&lt;T&gt; 那样同步,除非您当然想要那个开销)。这可能是您最好的选择,因为他们(Sun)通常会对这些领域进行大量研究(无论如何我所见)。如果您需要按“默认”以外的其他内容进行排序(即您没有对整数列表等进行排序),请提供您自己的比较器。

编辑:唯一不符合您要求的是快速删除...

【讨论】:

    【解决方案7】:

    Java 标准库中没有这样的容器。

    当我需要具有这些属性的数据结构时,我使用List 实现(通常是ArrayList,但没关系),并且我使用Collections.binarySearch 进行所有插入。

    如果我必须将排序列表封装为可重用类,我会实现 List 接口,将所有方法委托给“标准”List 实现(它甚至可以作为参数传递给构造函数)。我会通过抛出异常(UnsupportedOperationException)来实现每个插入方法(add、addAll、set、Iterator's remove),这样没有人可以破坏“始终排序”的属性。最后,我将提供一个方法insertSorted,它会使用Collections.binarySearch 进行插入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-29
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 2020-01-29
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多