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

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

内部类

image.png

方法一览

image.pngimage.pngimage.pngimage.pngimage.pngimage.png
image.png

打印数组 / toString

使用 Arrays.toString() 可以很方便的打印数组

  1. Integer[] integers = {1, 2, 3, 124, 61, 61};
  2. // 遍历数组,输出内容
  3. // for (int i = 0; i < integers.length; i++) {
  4. // System.out.println(integers[i]);
  5. // }
  6. // Arrays.toString
  7. System.out.println(Arrays.toString(integers));

源码

  1. /**
  2. * Returns a string representation of the contents of the specified array.
  3. * The string representation consists of a list of the array's elements,
  4. * enclosed in square brackets (<tt>"[]"</tt>). Adjacent elements are
  5. * separated by the characters <tt>", "</tt> (a comma followed by a
  6. * space). Elements are converted to strings as by
  7. * <tt>String.valueOf(char)</tt>. Returns <tt>"null"</tt> if <tt>a</tt>
  8. * is <tt>null</tt>.
  9. *
  10. * @param a the array whose string representation to return
  11. * @return a string representation of <tt>a</tt>
  12. * @since 1.5
  13. */
  14. public static String toString(char[] a) {
  15. if (a == null)
  16. return "null";
  17. int iMax = a.length - 1;
  18. if (iMax == -1)
  19. return "[]";
  20. StringBuilder b = new StringBuilder();
  21. b.append('[');
  22. for (int i = 0; ; i++) {
  23. b.append(a[i]);
  24. if (i == iMax)
  25. return b.append(']').toString();
  26. b.append(", ");
  27. }
  28. }

可以看到,底层使用的也是 for 循环。

排序 / sort

因为数组是引用类型,所以通过 Arrays.sort(Object[] a) 排序后,会影响到实参。

  1. Integer[] integers1 = {1, 2, -13, 124, 6, 16, 61, 61};
  2. Integer[] integers2 = {1, 2, -13, 124, 6, 16, 61, 61};
  3. // 冒泡排序
  4. for (int i = 0; i < integers1.length - 1; i++) {
  5. for (int j = 0; j < integers1.length - 1 - i; j++) {
  6. if (integers1[j] > integers1[j + 1]) {
  7. Integer temp = integers1[j];
  8. integers1[j] = integers1[j + 1];
  9. integers1[j + 1] = temp;
  10. }
  11. }
  12. }
  13. // Arrays.sort 排序
  14. Arrays.sort(integers2);
  15. System.out.println(Arrays.toString(integers1)); // [-13, 1, 2, 6, 16, 61, 61, 124]
  16. System.out.println(Arrays.toString(integers2)); // [-13, 1, 2, 6, 16, 61, 61, 124]

自定义规则排序

sort 函数是重载的,可以传入两个参数:
1)需要排序的数组
2)实现了 Comparable 接口的匿名内部类,要求实现 compare 方法

例1:

int[] ints = new int[]{1, 2, 34, 5, 65, 6, 1, 6};

// int[] 转 Integer[]
Integer[] integers = Arrays.stream(ints).boxed().toArray(Integer[]::new);

// 对 Integer[] 使用自定义 Comparator 排序
Arrays.sort(integers, new Comparator<Integer>() {
    @Override
    public int compare(Integer a, Integer b) {
        // 从大到小
        // return b - a;
        // 从小到大
        return a - b;
    }
});

System.out.println(Arrays.toString(integers)); // [1, 1, 2, 5, 6, 6, 34, 65]

例2:

import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        int[] integers1 = {1, 2, -13, 124, 6, 16, 61, 61};

        // 冒泡排序
//        bubble(integers1);
//        System.out.println(Arrays.toString(integers1));

        // 自定义规则的冒泡排序
        bubble_customize(integers1, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 从小到大
//                return o1 - o2;
                // 从大到小
                return o2 - o1;
            }
        });
        System.out.println(Arrays.toString(integers1));
    }

    // 冒泡排序 从小到大
    public static void bubble(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    // 自定义规则冒泡排序
    public static void bubble_customize(int[] arr, Comparator<Integer> c) {
        int temp = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (c.compare(arr[j], arr[j + 1]) > 0) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}

看一下源码:

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, 0, a.length, c, null, 0, 0);
    }
}

二分查找 / binarySearch

binarySearch(int[] a, int key)

使用二叉搜索算法搜索指定的int数组的指定值。 在进行此调用之前,必须对数组进行排序(如 sort( int[] a) 方法)。 如果没有排序,结果是未定义的。 如果数组包含具有指定值的多个元素,则不能保证将找到那个元素。

int[] integers1 = {-13, 1, 2, 6, 16, 61, 61, 124};

System.out.println(Arrays.binarySearch(integers1, 6)); // 3
System.out.println(Arrays.binarySearch(integers1, 5)); // -6

返回的是 key 在搜索数组中的下标,那么为什么第二个会返回 -6 呢?

看一下源码:

public static int binarySearch(int[] a, int key) {
    return binarySearch0(a, 0, a.length, key);
}
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                 int key) {
    int low = fromIndex;
    int high = toIndex - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = a[mid];

        if (midVal < key)
            low = mid + 1;
        else if (midVal > key)
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found.
}

可以看到,如果是 key not found ,返回值是 -(low +1) 。

这里的 low 可以理解为,如果把这个 key 插入有序数组,它应该处于哪个下标。

实际上,这个 low 也就是二分查找时,左侧的边界下标值。

复制数组 / copyOf

使用 copyOf(int[] original, int newLength) 可以复制一个数组,且复制出来的数组对象和原本被复制的数组对象不同。是深拷贝。

使用 clone 方法也一样,是深拷贝。

int[] integers1 = {-13, 1, 2, 6, 16, 61, 61, 124};

// Arrays.copyOf
int[] copy = Arrays.copyOf(integers1, integers1.length);
System.out.println(integers1 == copy); // false
System.out.println(Arrays.toString(copy)); // [-13, 1, 2, 6, 16, 61, 61, 124]

// clone
int[] copy2 = integers1.clone();
System.out.println(integers1 == copy2); // false
System.out.println(Arrays.toString(copy2)); // [-13, 1, 2, 6, 16, 61, 61, 124]

填充数组 / fill

fill(int[] a, int val) 将指定的int值分配给指定的int数组的每个元素

int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
Arrays.fill(arr, 99);
System.out.println(Arrays.toString(arr)); // [99, 99, 99, 99, 99, 99, 99, 99, 99]

比较两个数组元素内容是否相等 / equals

equals(int[] a, int[] a2)

int[] integers1 = {-13, 1, 2, 6, 16, 61, 61, 124};
int[] integers2 = {-13, 1, 2, 6, 16, 61, 61, 124};
int[] integers3 = {-13, 1, 2, 6, 16, 61, 61};

System.out.println(Arrays.equals(integers1, integers2)); // true
System.out.println(Arrays.equals(integers2, integers3)); // false

将一组值转换为 list /

返回由指定数组支持的固定大小的列表。 (将返回的列表更改为“写入数组”。)该方法作为基于数组和基于集合的API之间的桥梁,与Collection.toArray()相结合 。 返回的列表是可序列化的,并实现RandomAccess 。

此方法还提供了一种方便的方式来创建一个初始化为包含几个元素的固定大小的列表: List stooges = Arrays.asList(“Larry”, “Moe”, “Curly”);

Object obj = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(obj); // [1, 2, 3, 4, 5]
System.out.println(obj.getClass()); // class java.util.Arrays$ArrayList

asList 的源码:

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