从源码分析Arrays类的常用方法

x33g5p2x  于2021-12-31 转载在 其他  
字(7.2k)|赞(0)|评价(0)|浏览(447)

Arrays类概述

Arrays类在源码中的声明:

  1. /** * This class contains various methods for manipulating arrays (such as * sorting and searching). This class also contains a static factory * that allows arrays to be viewed as lists. * * <p>The methods in this class all throw a {@code NullPointerException}, * if the specified array reference is null, except where noted. * * <p>The documentation for the methods contained in this class includes * briefs description of the <i>implementations</i>. Such descriptions should * be regarded as <i>implementation notes</i>, rather than parts of the * <i>specification</i>. Implementors should feel free to substitute other * algorithms, so long as the specification itself is adhered to. (For * example, the algorithm used by {@code sort(Object[])} does not have to be * a MergeSort, but it does have to be <i>stable</i>.) * * <p>This class is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. */
  2. public class Arrays

Arrays类可以看做是一个数组工具类,它包含了用于操作数组的各种方法(如排序和搜索)。 该类还包含一个静态工厂,可以将数组视为列表。

如果指定的数组引用为空,则该类中的方法都抛出一个NullPointerException ,除非另有说明。

常用方法

Arrays类中的排序调用DualPivotQuicksort类中的排序方法实现。

关于DualPivotQuicksort类的声明如下:

  1. /** * This class implements the Dual-Pivot Quicksort algorithm by * Vladimir Yaroslavskiy, Jon Bentley, and Josh Bloch. The algorithm * offers O(n log(n)) performance on many data sets that cause other * quicksorts to degrade to quadratic performance, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * All exposed methods are package-private, designed to be invoked * from public methods (in class Arrays) after performing any * necessary array bounds checks and expanding parameters into the * required forms. */
  2. final class DualPivotQuicksort

DualPivotQuicksort被称为双轴快速排序,它汇集了多种排序算法,包括 优化后的归并排序(Timsort)、插入排序,成对插入排序、单轴快速排序,双轴快速排序
、计数排序。

DualPivotQuicksort源码见:DualPivotQuicksort源码

排序sort

它提供了对int、long、short、char、byte、float、double、object型数组的排序方法。

  1. //按照数字顺序排列指定的数组。
  2. public static void sort(int[] a) {
  3. DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
  4. }
  5. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  6. public static void sort(int[] a, int fromIndex, int toIndex) {
  7. rangeCheck(a.length, fromIndex, toIndex);
  8. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
  9. }
  10. //按照数字顺序排列指定的数组。
  11. public static void sort(long[] a) {
  12. DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
  13. }
  14. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  15. public static void sort(long[] a, int fromIndex, int toIndex) {
  16. rangeCheck(a.length, fromIndex, toIndex);
  17. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
  18. }
  19. //按照数字顺序排列指定的数组。
  20. public static void sort(short[] a) {
  21. DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
  22. }
  23. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  24. public static void sort(short[] a, int fromIndex, int toIndex) {
  25. rangeCheck(a.length, fromIndex, toIndex);
  26. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
  27. }
  28. //按照数字顺序排列指定的数组。
  29. public static void sort(char[] a) {
  30. DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
  31. }
  32. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  33. public static void sort(char[] a, int fromIndex, int toIndex) {
  34. rangeCheck(a.length, fromIndex, toIndex);
  35. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
  36. }
  37. //按照数字顺序排列指定的数组。
  38. public static void sort(byte[] a) {
  39. DualPivotQuicksort.sort(a, 0, a.length - 1);
  40. }
  41. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  42. public static void sort(byte[] a, int fromIndex, int toIndex) {
  43. rangeCheck(a.length, fromIndex, toIndex);
  44. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1);
  45. }
  46. //按照数字顺序排列指定的数组。
  47. public static void sort(float[] a) {
  48. DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
  49. }
  50. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  51. public static void sort(float[] a, int fromIndex, int toIndex) {
  52. rangeCheck(a.length, fromIndex, toIndex);
  53. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
  54. }
  55. //按照数字顺序排列指定的数组。
  56. public static void sort(double[] a) {
  57. DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
  58. }
  59. //在指定范围对指定数组进行升序排序。 要排序的范围从索引fromIndex (包括)扩展到索引toIndex(不包括)。 如果fromIndex == toIndex ,要排序的范围是空的。
  60. public static void sort(double[] a, int fromIndex, int toIndex) {
  61. rangeCheck(a.length, fromIndex, toIndex);
  62. DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
  63. }

除此之外,Arrays中还提供了许多其他类型的排序方法,如并行排序、归并排序等,这里不再一一例举。

搜索binarySearch

Arrays提供binarySearch二分查找方法,binarySearch()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的查找需要。

  1. // 使用二叉搜索算法搜索指定的int数组的指定值。 在进行此调用之前,必须对数组进行排序(如sort(int[])方法)。 如果没有排序,结果是未定义的。
  2. public static int binarySearch(int[] a, int key) {
  3. return binarySearch0(a, 0, a.length, key);
  4. }
  5. //使用二叉搜索算法在指定数组的指定范围内搜索指定值。
  6. public static int binarySearch(int[] a, int fromIndex, int toIndex,
  7. int key) {
  8. rangeCheck(a.length, fromIndex, toIndex);
  9. return binarySearch0(a, fromIndex, toIndex, key);
  10. }
  11. private static int binarySearch0(int[] a, int fromIndex, int toIndex,
  12. int key) {
  13. int low = fromIndex;
  14. int high = toIndex - 1;
  15. while (low <= high) {
  16. int mid = (low + high) >>> 1;
  17. int midVal = a[mid];
  18. if (midVal < key)
  19. low = mid + 1;
  20. else if (midVal > key)
  21. high = mid - 1;
  22. else
  23. return mid; // key found
  24. }
  25. return -(low + 1); // key not found.
  26. }

这里只例举了int型数组的搜索,其他类型的数组搜索比较类似。

比较equals

Arrays中也提供了equals方法,比较两者是否相等。

equals()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

  1. public static boolean equals(int[] a, int[] a2) {
  2. if (a==a2)
  3. return true;
  4. if (a==null || a2==null)
  5. return false;
  6. int length = a.length;
  7. if (a2.length != length)
  8. return false;
  9. for (int i=0; i<length; i++)
  10. if (a[i] != a2[i])
  11. return false;
  12. return true;
  13. }

填充fill

Arrays中还提供了fill方法,用于将指定值填充在指定数组的每个元素(或指定范围的所有元素)。

fill()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

  1. //将指定的int值分配给指定的int数组的每个元素。
  2. public static void fill(int[] a, int val) {
  3. for (int i = 0, len = a.length; i < len; i++)
  4. a[i] = val;
  5. }
  6. // 将指定的int值分配给指定的int数组的指定范围的每个元素。 要填充的范围从索引fromIndex扩展到索引toIndex。 (如果fromIndex==toIndex ,要填充的范围是空的。)
  7. public static void fill(int[] a, int fromIndex, int toIndex, int val) {
  8. rangeCheck(a.length, fromIndex, toIndex);
  9. for (int i = fromIndex; i < toIndex; i++)
  10. a[i] = val;
  11. }

赋值copyOf

copyOf方法用于复制指定数组,得到原始数组的副本,截断或填充空值以获取指定的长度 。

copyOf()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

  1. public static <T> T[] copyOf(T[] original, int newLength) {
  2. return (T[]) copyOf(original, newLength, original.getClass());
  3. }
  4. public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
  5. @SuppressWarnings("unchecked")
  6. T[] copy = ((Object)newType == (Object)Object[].class)
  7. ? (T[]) new Object[newLength]
  8. : (T[]) Array.newInstance(newType.getComponentType(), newLength);
  9. System.arraycopy(original, 0, copy, 0,
  10. Math.min(original.length, newLength));
  11. return copy;
  12. }

将数组转换成列表asList

  1. public static <T> List<T> asList(T... a) {
  2. return new ArrayList<>(a);
  3. }

获取哈希码hashCode

hashCode用于根据指定数组的内容返回哈希码。

hashCode()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

  1. public static int hashCode(long a[]) {
  2. if (a == null)
  3. return 0;
  4. int result = 1;
  5. for (long element : a) {
  6. int elementHash = (int)(element ^ (element >>> 32));
  7. result = 31 * result + elementHash;
  8. }
  9. return result;
  10. }

toString

返回指定数组的内容的字符串表示形式。 字符串表示由数组元素的列表组成,括在方括号( “[]” )中。 相邻的元素由字符", "分隔(逗号后跟一个空格)。

toString()方法提供了多种重载形式,用于满足各种类型数组(int、long、short、char、byte、float、double、object型)的需要。

  1. public static String toString(long[] a) {
  2. if (a == null)
  3. return "null";
  4. int iMax = a.length - 1;
  5. if (iMax == -1)
  6. return "[]";
  7. StringBuilder b = new StringBuilder();
  8. b.append('[');
  9. for (int i = 0; ; i++) {
  10. b.append(a[i]);
  11. if (i == iMax)
  12. return b.append(']').toString();
  13. b.append(", ");
  14. }
  15. }

相关文章