Java Arrays.sort源代码解析

本文详细解析了Java中Arrays.sort()方法的工作原理,包括针对基本类型和对象类型的排序算法优化,以及源码级别的深入探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本类型:采用调优的快速排序(Primitive(int,float等原型数据));
对象类型:采用改进的归并排序(Object对象数组)。

源码中选择划分元的方法:

    当数组大小为 size=7 时 ,取数组中间元素作为划分元。int n=m>>1;(此方法值得借鉴)

    当数组大小7< size<=40时,取首、中、末三个元素中间大小的元素作为划分元。

    当数组大小 size>40 时 ,从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元。

根据划分元 v ,形成不变式 v* (v)* v*

  普通的快速排序算法,经过一次划分后,将划分元排到素组较中间的位置,左边的元素小于划分元,右边的元素大于划分元,而没有将与划分元相等的元素放在其附近,这一点,在Arrays.sort()中得到了较大的优化。

  举例:15、93、15、41、6、15、22、7、15、20

  因 7

  经过一次换分后: 15、15、7、6、41、20、22、93、15、15. 与划分元相等的元素都移到了素组的两边。

  接下来将与划分元相等的元素移到数组中间来,形成:7、6、15、15、15、15、41、20、22、93.

  最后递归对两个区间进行排序[7、6]和[41、20、22、93]. 
  

  1. package com.util;
  2. import java.lang.reflect.Array;
  3. public class ArraysObject {
  4. private static final int INSERTIONSORT_THRESHOLD = 7;
  5. private ArraysObject() {}
  6. public static void sort(Object[] a) {
  7. //java.lang.Object.clone(),理解深表复制和浅表复制
  8. Object[] aux = (Object[]) a.clone();
  9. mergeSort(aux, a, 0, a.length, 0);
  10. }
  11. public static void sort(Object[] a, int fromIndex, int toIndex) {
  12. rangeCheck(a.length, fromIndex, toIndex);
  13. Object[] aux = copyOfRange(a, fromIndex, toIndex);
  14. mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
  15. }
  16. /**
  17. * Src is the source array that starts at index 0
  18. * Dest is the (possibly larger) array destination with a possible offset
  19. * low is the index in dest to start sorting
  20. * high is the end index in dest to end sorting
  21. * off is the offset to generate corresponding low, high in src
  22. */
  23. private static void mergeSort(Object[] src, Object[] dest, int low,
  24. int high, int off) {
  25. int length = high - low;
  26. // Insertion sort on smallest arrays
  27. if (length < INSERTIONSORT_THRESHOLD) {
  28. for (int i = low; i < high; i++)
  29. for (int j = i; j > low &&
  30. ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
  31. swap(dest, j, j - 1);
  32. return;
  33. }
  34. // Recursively sort halves of dest into src
  35. int destLow = low;
  36. int destHigh = high;
  37. low += off;
  38. high += off;
  39. /*
  40. * >>>:无符号右移运算符
  41. * expression1 >>> expresion2:expression1的各个位向右移expression2
  42. * 指定的位数。右移后左边空出的位数用0来填充。移出右边的位被丢弃。
  43. * 例如:-14>>>2; 结果为:1073741820
  44. */
  45. int mid = (low + high) >>> 1;
  46. mergeSort(dest, src, low, mid, -off);
  47. mergeSort(dest, src, mid, high, -off);
  48. // If list is already sorted, just copy from src to dest. This is an
  49. // optimization that results in faster sorts for nearly ordered lists.
  50. if (((Comparable) src[mid - 1]).compareTo(src[mid]) <= 0) {
  51. System.arraycopy(src, low, dest, destLow, length);
  52. return;
  53. }
  54. // Merge sorted halves (now in src) into dest
  55. for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
  56. if (q >= high || p < mid
  57. && ((Comparable) src[p]).compareTo(src[q]) <= 0)
  58. dest[i] = src[p++];
  59. else
  60. dest[i] = src[q++];
  61. }
  62. }
  63. /**
  64. * Check that fromIndex and toIndex are in range, and throw an appropriate
  65. * exception if they aren't.
  66. */
  67. private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
  68. if (fromIndex > toIndex)
  69. throw new IllegalArgumentException("fromIndex(" + fromIndex
  70. + ") > toIndex(" + toIndex + ")");
  71. if (fromIndex < 0)
  72. throw new ArrayIndexOutOfBoundsException(fromIndex);
  73. if (toIndex > arrayLen)
  74. throw new ArrayIndexOutOfBoundsException(toIndex);
  75. }
  76. public static <T> T[] copyOfRange(T[] original, int from, int to) {
  77. return copyOfRange(original, from, to, (Class<T[]>) original.getClass());
  78. }
  79. public static <T, U> T[] copyOfRange(U[] original, int from, int to,
  80. Class<? extends T[]> newType) {
  81. int newLength = to - from;
  82. if (newLength < 0)
  83. throw new IllegalArgumentException(from + " > " + to);
  84. T[] copy = ((Object) newType == (Object) Object[].class)
  85. ? (T[]) new Object[newLength]
  86. : (T[]) Array.newInstance(newType.getComponentType(), newLength);
  87. System.arraycopy(original, from, copy, 0,
  88. Math.min(original.length - from, newLength));
  89. return copy;
  90. }
  91. /**
  92. * Swaps x[a] with x[b].
  93. */
  94. private static void swap(Object[] x, int a, int b) {
  95. Object t = x[a];
  96. x[a] = x[b];
  97. x[b] = t;
  98. }
  99. }

对于Object类型源码分析如下

  1. package com.util;
  2. import java.lang.reflect.Array;
  3. public class ArraysObject {
  4. private static final int INSERTIONSORT_THRESHOLD = 7;
  5. private ArraysObject() {}
  6. public static void sort(Object[] a) {
  7. //java.lang.Object.clone(),理解深表复制和浅表复制
  8. Object[] aux = (Object[]) a.clone();
  9. mergeSort(aux, a, 0, a.length, 0);
  10. }
  11. public static void sort(Object[] a, int fromIndex, int toIndex) {
  12. rangeCheck(a.length, fromIndex, toIndex);
  13. Object[] aux = copyOfRange(a, fromIndex, toIndex);
  14. mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
  15. }
  16. /**
  17. * Src is the source array that starts at index 0
  18. * Dest is the (possibly larger) array destination with a possible offset
  19. * low is the index in dest to start sorting
  20. * high is the end index in dest to end sorting
  21. * off is the offset to generate corresponding low, high in src
  22. */
  23. private static void mergeSort(Object[] src, Object[] dest, int low,
  24. int high, int off) {
  25. int length = high - low;
  26. // Insertion sort on smallest arrays
  27. if (length < INSERTIONSORT_THRESHOLD) {
  28. for (int i = low; i < high; i++)
  29. for (int j = i; j > low &&
  30. ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
  31. swap(dest, j, j - 1);
  32. return;
  33. }
  34. // Recursively sort halves of dest into src
  35. int destLow = low;
  36. int destHigh = high;
  37. low += off;
  38. high += off;
  39. /*
  40. * >>>:无符号右移运算符
  41. * expression1 >>> expresion2:expression1的各个位向右移expression2
  42. * 指定的位数。右移后左边空出的位数用0来填充。移出右边的位被丢弃。
  43. * 例如:-14>>>2; 结果为:1073741820
  44. */
  45. int mid = (low + high) >>> 1;
  46. mergeSort(dest, src, low, mid, -off);
  47. mergeSort(dest, src, mid, high, -off);
  48. // If list is already sorted, just copy from src to dest. This is an
  49. // optimization that results in faster sorts for nearly ordered lists.
  50. if (((Comparable) src[mid - 1]).compareTo(src[mid]) <= 0) {
  51. System.arraycopy(src, low, dest, destLow, length);
  52. return;
  53. }
  54. // Merge sorted halves (now in src) into dest
  55. for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
  56. if (q >= high || p < mid
  57. && ((Comparable) src[p]).compareTo(src[q]) <= 0)
  58. dest[i] = src[p++];
  59. else
  60. dest[i] = src[q++];
  61. }
  62. }
  63. /**
  64. * Check that fromIndex and toIndex are in range, and throw an appropriate
  65. * exception if they aren't.
  66. */
  67. private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
  68. if (fromIndex > toIndex)
  69. throw new IllegalArgumentException("fromIndex(" + fromIndex
  70. + ") > toIndex(" + toIndex + ")");
  71. if (fromIndex < 0)
  72. throw new ArrayIndexOutOfBoundsException(fromIndex);
  73. if (toIndex > arrayLen)
  74. throw new ArrayIndexOutOfBoundsException(toIndex);
  75. }
  76. public static <T> T[] copyOfRange(T[] original, int from, int to) {
  77. return copyOfRange(original, from, to, (Class<T[]>) original.getClass());
  78. }
  79. public static <T, U> T[] copyOfRange(U[] original, int from, int to,
  80. Class<? extends T[]> newType) {
  81. int newLength = to - from;
  82. if (newLength < 0)
  83. throw new IllegalArgumentException(from + " > " + to);
  84. T[] copy = ((Object) newType == (Object) Object[].class)
  85. ? (T[]) new Object[newLength]
  86. : (T[]) Array.newInstance(newType.getComponentType(), newLength);
  87. System.arraycopy(original, from, copy, 0,
  88. Math.min(original.length - from, newLength));
  89. return copy;
  90. }
  91. /**
  92. * Swaps x[a] with x[b].
  93. */
  94. private static void swap(Object[] x, int a, int b) {
  95. Object t = x[a];
  96. x[a] = x[b];
  97. x[b] = t;
  98. }
  99. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值