java.util.Arrays uses quicksort (actually dual pivot quicksort in the most recent version) for primitive types such as int and mergesort for objects that implement Comparable or use a Comparator. Why the difference? Why not pick one and use it for all cases?
2 Answers
A good explanation here:-
Quicksort is faster in both cases. Mergesort is stable in both cases. But for primitive types quicksort is stable too! That’s because primitive types in Java are like elementary particles in quantum mechanics. You can’t tell the difference between one 7 and another 7. Their value is all that defines them. Sort the array such [7, 6, 6, 7, 6, 5, 4, 6, 0] into [0, 4, 5, 6, 6, 6, 6, 7, 7]. Not only do you not care which 6 ended up in which position. It’s a meaningless question. The array positions don’t hold pointers to the objects. They hold the actual values of the objects. We might as well say that all the original values were thrown away and replaced with new ones. Or not. It just doesn’t matter at all. There is no possible way you can tell the difference between the output of a stable and unstable sorting algorithm when all that’s sorted are primitive types. Stability is irrelevant with primitive types in Java.
1 Comment
I think that the reason is stability.
The primitives do not have an identity, so it is impossible to distinguish between 2 integers with the same value. This is not the case for referenced types this might be problematic as quick sort might change their relative positions and that is why a more stable merge sort is used.
Also, not using n*log n for primitives might be because it would require a clone of an array. For reference types it does not really matter as they arrays of objects are normally bigger than the corresponding arrays of references. However, for primitives clonning uses double memory.