Java:就地对 ArrayList 进行排序
Posted
技术标签:
【中文标题】Java:就地对 ArrayList 进行排序【英文标题】:Java: sorting an ArrayList in place 【发布时间】:2011-12-20 06:33:26 【问题描述】:在 Java 的标准库中,是否有一种方法可以就地对 ArrayList
进行排序,即使用 O(1)
额外存储空间?
Collections.sort(List<T>)
不满足此要求,因为它
将指定的列表转储到一个数组中,对数组进行排序,然后遍历列表,从数组中的相应位置重置每个元素。
如果标准库中什么都没有,有哪些第三方库可以做到这一点?
【问题讨论】:
【参考方案1】:从 Java 8 开始,List
接口具有默认的void sort(Comparator<? super E> c)
API,您可以使用它对实例进行就地排序。
列表必须是可修改的、可迭代的,并且它的元素可以相互比较。
【讨论】:
【参考方案2】:Collections.sort()
可以与任何 List 实现一起使用,这就是它无法正常工作的原因(合并 LinkedList 很困难并且会牺牲稳定性)。
如果您真的担心就地排序,则必须推出自己的排序功能。除非您的列表很长,否则不值得您花时间。
Arrays.sort(Object[])
执行相同的归并排序,并由Collections.sort()
内部调用(至少在 openjdk 中)
【讨论】:
您可以使用 ArrayList 而不是数组来复制此处描述的堆排序:[link]en.wikibooks.org/wiki/Algorithm_Implementation/Sorting/Heapsort)【参考方案3】:您可以提取底层数组(例如反射)并对其执行 Arrays.sort(array, 0, list.size())。
Java 7 在对数组进行排序之前不会复制 Arrays.sort() 中的数组。在 Java 6 中,这意味着 Java 6 中的 Collections.sort() 实际上复制了底层数组 TWICE 来执行排序。
【讨论】:
唯一的事情是这需要一个数组的副本,因此根据 Collections.sort 使用 O(n) 额外存储。 在 Java 7 中不需要复制。我还没有检查过 Java 6。 有趣。我真的很惊讶他们改变了返回底层数组的行为;可以想象这会给从 Java 6 升级的人带来很多微妙的错误。 Arrays.sort() 不返回任何内容。问题是它是否在排序之前复制数组。 在 Java 8 中Collections.sort
调用列表上的 sort
,所以这取决于列表实现。 ArrayList
使用其元素数组调用 Arrays.sort
,所以它仍然存在。以上是关于Java:就地对 ArrayList 进行排序的主要内容,如果未能解决你的问题,请参考以下文章