简体   繁体   English

为什么Java的排序实现在排序之前将列表转换为数组?

[英]Why does Java's sort implementation convert a list to an array before sorting?

In JDK 1.8, the first statement of the java.util.List#sort(Comparator) method is the following: 在JDK 1.8中, java.util.List#sort(Comparator)方法的第一个语句如下:

Object[] a = this.toArray();

It's expensive to copy the list into an array, sort it, and reset every node of the list to the sorted value from the array. 将列表复制到数组中,对其进行排序,并将列表中的每个节点重置为数组中的排序值是很昂贵的。

It seems like it's possible not to copy values to a temporary array when sorting an ArrayList . 在排序ArrayList时,似乎不可能将值复制到临时数组。 Am I right? 我对吗? If not, what guided the creators of the method? 如果没有,是什么引导了该方法的创造者?

The sort in the java.util.List interface is just the default implementation of the list sort. java.util.List接口中的sort只是列表排序的默认实现。

ArrayList overrides this default with a sort method which does sort its internal array directly. ArrayList使用sort方法覆盖此缺省值,该方法直接对其内部数组进行排序。

For ArrayList, or other random access Lists, you may be correct. 对于ArrayList或其他随机访问列表,您可能是正确的。

However, Collections.sort supports any List implementation. 但是,Collections.sort支持任何List实现。 For a LinkedList, for example, it would have been very expansive to swap elements during the sort (since finding the i'th element takes linear time). 例如,对于LinkedList,在排序期间交换元素会非常广泛(因为找到第i个元素需要线性时间)。

Converting the List to an array, and setting the elements of the original List after the array is sorted adds a linear time component to the algorithm, which doesn't change the asymptotic running time of (O(nlog(n))) . 将List转换为数组,并在对数组进行排序后设置原始List的元素会为算法添加线性时间组件,这不会更改(O(nlog(n)))的渐近运行时间。

In OpenJDK 1.8, java.util.ArrayList#sort(Comparator) does not copy its internal array; 在OpenJDK 1.8中, java.util.ArrayList#sort(Comparator)不复制其内部数组; it sorts in place, as you suggest it should. 正如你所建议的那样,它就地排序了。

The implementation of java.util.List#sort() you're criticizing has the following accompanying documentation: 您批评的java.util.List#sort()的实现具有以下随附文档:

The default implementation obtains an array containing all elements in this list, sorts the array, and iterates over this list resetting each element from the corresponding position in the array. 默认实现获取包含此列表中所有元素的数组,对数组进行排序,并迭代此列表,从数组中的相应位置重置每个元素。 (This avoids the n² log(n) performance that would result from attempting to sort a linked list in place.) (这样可以避免尝试对链接列表进行排序所导致的n²log(n)性能。)

That is, copying the array and moving around with random access is more efficient than the overhead of striding around linearly in a linked list. 也就是说,复制数组并随机访问移动比在链表中线性移动的开销更有效。 The common implementation attempts to trade copying overhead for element access overhead. 通用实现尝试交换元素访问开销的复制开销。 For cases like ArrayList where the copying isn't necessary to get the same random access to elements, the library omits the copy by overriding the method. 对于像ArrayList这样的情况,其中不需要复制来获得对元素的相同随机访问,库通过覆盖该方法来省略该复制。

An interesting comparison: Look at the C++ Standard Library's std::sort() and std::list::sort() functions: 一个有趣的比较:看看C ++标准库的std::sort()std::list::sort()函数:

  • std::sort() Requires parameters that delimit a range with random access . std::sort()需要使用随机访问来分隔范围的参数。
  • std::list::sort() Assumes only linear access by traversing linked list nodes. std::list::sort()通过遍历链表节点仅假设线性访问

The generic std::sort() algorithm is more efficient, but the library precludes calling it on a std::list (which is a linked list, akin to Java's java.util.LinkedList ). 通用的std::sort()算法效率更高,但是库阻止在std::list (它是一个链表,类似于Java的java.util.LinkedList )上调用它。 The library provides a less efficient means to sort a std::list for convenience. 为方便起见,该库提供了一种不太有效的方法来对std::list进行排序。 Unlike the Java library, the C++ library does not copy a std::list() to an array in order to use the random access std::sort() algorithm. 与Java库不同,C ++库不会将std::list()复制到数组,以便使用随机访问std::sort()算法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我在Java中的快速排序实现仅对数组的一部分进行排序。 不知道为什么要这么做 - My Quick Sort implementation in Java is sorting only part of the array. Not sure why it's doing this 为什么 Java 的 Arrays.sort 方法对不同的类型使用两种不同的排序算法? - Why does Java's Arrays.sort method use two different sorting algorithms for different types? 使用Java中的插入排序算法对数组列表中的温度进行排序 - Sorting temperatures in a array list using insertion sort algorithm in java 为什么我的冒泡排序算法实现对整个数组进行排序并跳过第一个索引? - Why is my bubble sort algorithm implementation sorting the entire array and skips the first index? 在Java中对数组列表进行排序 - Sorting array list in Java Java int 数组和 char 数组实现:为什么这样做? - Java int array and char array implementation: why does this work? 在Java中列出类的toArray-为什么我不能将“Integer”列表转换为“Integer”数组? - List class's toArray in Java- Why can't I convert a list of “Integer” to an “Integer” array? 为什么不对列表进行排序? - Why does this not sort the list? 为什么Collections.sort(List)在Java 8中使用CopyOnWriteArrayList但在Java 7中不起作用? - Why does Collections.sort(List) work in Java 8 with CopyOnWriteArrayList but not in Java 7? 为什么Java的List有“List.toArray()”,但是数组没有“Array.toList()”? - Why does Java's List have “List.toArray()”, but arrays don't have “Array.toList()”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM