【发布时间】:2011-12-20 06:33:26
【问题描述】:
在 Java 的标准库中,是否有一种方法可以就地对 ArrayList 进行排序,即使用 O(1) 额外存储空间?
Collections.sort(List<T>) 不满足此要求,因为它
将指定的列表转储到一个数组中,对数组进行排序,然后遍历列表,从数组中的相应位置重置每个元素。
如果标准库中什么都没有,有哪些第三方库可以做到这一点?
【问题讨论】:
在 Java 的标准库中,是否有一种方法可以就地对 ArrayList 进行排序,即使用 O(1) 额外存储空间?
Collections.sort(List<T>) 不满足此要求,因为它
将指定的列表转储到一个数组中,对数组进行排序,然后遍历列表,从数组中的相应位置重置每个元素。
如果标准库中什么都没有,有哪些第三方库可以做到这一点?
【问题讨论】:
从 Java 8 开始,List 接口具有默认的void sort(Comparator<? super E> c) API,您可以使用它对实例进行就地排序。
列表必须是可修改的、可迭代的,并且它的元素可以相互比较。
【讨论】:
Collections.sort() 可以与任何 List 实现一起使用,这就是它无法正常工作的原因(合并 LinkedList 很困难并且会牺牲稳定性)。
如果您真的担心就地排序,则必须推出自己的排序功能。除非您的列表很长,否则不值得您花时间。
Arrays.sort(Object[]) 执行相同的归并排序,并由Collections.sort() 内部调用(至少在 openjdk 中)
【讨论】:
您可以提取底层数组(例如反射)并对其执行 Arrays.sort(array, 0, list.size())。
Java 7 在对数组进行排序之前不会复制 Arrays.sort() 中的数组。在 Java 6 中,这意味着 Java 6 中的 Collections.sort() 实际上复制了底层数组 TWICE 来执行排序。
【讨论】:
Collections.sort 调用列表上的 sort,所以这取决于列表实现。 ArrayList 使用其元素数组调用 Arrays.sort,所以它仍然存在。