Java——Arrays 类详解

一、Arrays 类简介

Arrays 类是 Java 语言中用于操作数组的一个工具类,提供了多种静态方法来处理数组,包括排序、搜索、填充、比较等操作。这个类位于 java.util 包中。

Arrays类的构造方法被设置为私有(private),因此无法创建 Arrays 对象。Arrays 类的所有公有方法都是静态的,可以直接通过类名调用。

二、常用方法

1、Arrays.toString()

1)使用示例

返回数组的字符串表示。

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[] arr = {1, 2, 3, 4, 5, 6};

System.out.println(Arrays.toString(arr));

}

}

运行结果:

2)源码

我们可以查看这个方法的源码:

public static String toString(int[] a) {

if (a == null) // 判断 a 是否为空引用,如果为空引用,则返回 "null" 字符串

return "null";

int iMax = a.length - 1;

if (iMax == -1) // 判断数组内容是否为空,如果内容为空,则返回 "[]" 字符串

return "[]";

StringBuilder b = new StringBuilder();

b.append('[');

for (int i = 0; ; i++) {

b.append(a[i]); // 依次将数组的元素追加到字符串中

if (i == iMax) // 判断是否为最后一个元素,如果是最后一个元素,则返回最终的字符串

return b.append(']').toString();

b.append(", ");

}

}

所以说这个方法使用的依旧是对数组进行遍历。

2、Arrays.copyOf()

复制数组,可以指定新数组的长度。

1)使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

// 原始数组

int[] originalArray = {1, 2, 3, 4, 5};

// 复制数组,指定新数组的长度

// 新数组长度小于原数组长度

int[] newArray1 = Arrays.copyOf(originalArray, 3);

System.out.println("新数组1: " + Arrays.toString(newArray1)); // 输出: [1, 2, 3]

// 新数组长度大于原数组长度

int[] newArray2 = Arrays.copyOf(originalArray, 8);

System.out.println("新数组2: " + Arrays.toString(newArray2)); // 输出: [1, 2, 3, 4, 5, 0, 0, 0]

// 新数组长度等于原数组长度

int[] newArray3 = Arrays.copyOf(originalArray, originalArray.length);

System.out.println("新数组3: " + Arrays.toString(newArray3)); // 输出: [1, 2, 3, 4, 5]

}

}

运行结果:

也就是说第一个参数是源数组,第二个参数是从源数组中复制多少个元素到新数组中,如果第二个参数大于了源数组的大小,则新数组中大于源数组大小的部分的元素都是类型默认值。

3、Arrays.sort()

对数组内容进行排序。

1)简单使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[] arr = {11, 33, 99, 22, 88, 44, 55, 66, 77};

Arrays.sort(arr);

System.out.println(Arrays.toString(arr));

}

}

运行结果:

可以发现这里的顺序是升序排列,那如何实现降序排列呢,就要用到下面这种方式了。

2)带 Comparator 接口的 sort() 方法的使用

import java.util.Arrays;

import java.util.Comparator;

public class Example {

public static void main(String[] args) {

Integer[] arr = {11, 33, 99, 22, 88, 44, 55, 66, 77};

// 这里要使用 Integer 包装类

Arrays.sort(arr, new Comparator() {

@Override

public int compare(Integer o1, Integer o2) {

return o2 - o1;

}

});

System.out.println(Arrays.toString(arr));

}

}

运行结果:

这里的数组不能使用基本数据类型,因为这里的 sort() 方法的声明是这样的:

public static void sort(T[] a, Comparator c);

这里的 sort 是一个泛型方法,泛型参数只能接受类类型,所以这里需要使用包装类型数组作为第一个参数,对于第二个参数,我们传入的是:

new Comparator() {

@Override

public int compare(Integer o1, Integer o2) {

return o2 - o1;

}

}

这显然是一个匿名内部类,它实现了 Comparator 接口,同时重写了这个接口的 compare() 方法,这个方法是关键,这里返回值是 o2 - o1,这就代表了,如果 o1 如果大于 o2 的话,则返回负值,对于 sort() 方法内部某个地方就是调用的 compare() 方法来比较两个参数的大小。

如果是升序的话,o1 大于 o2 应当返回的是正值,这里返回了负值,所以就是将顺序设置为反的,所以最终可以得到降序的数组。

3)Arrays.sort() 使用的算法

基本类型数组(如 int[], char[] 等):

对于基本数据类型数组,Arrays.sort() 方法使用了一种名为 Dual-Pivot Quicksort 的排序算法。这是一种改进的快速排序算法,由 Vladimir Yaroslavskiy 提出。它在平均情况下具有 O(n log n) 的时间复杂度,并且在实践中通常表现良好。

对象类型数组(如 Integer[], String[] 等):

对于对象数组,Arrays.sort() 方法则使用 Timsort 算法。这是一种混合排序算法,结合了归并排序和插入排序的优点。Timsort 是为了优化对部分有序数据的排序而设计的,具有 O(n log n) 的时间复杂度,并且在实际应用中表现出色。4、Arrays.binarySearch()

在已排序的数组中进行二分查找。这个方法需要数组是有序的。

1)使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[] arr = {11, 22, 33, 44, 55, 66, 77, 88, 99};

// Arrays.sort(arr)

// 在调用 binarySearch 前需要对数组先进行排序

// 这里为了方便比对结果,数组已经是有序的

int index = Arrays.binarySearch(arr, 99);

System.out.println("index of 99: " + index);

}

}

运行结果:

2)源码

binarySearch() 方法内部会调用 binarySearch0() 方法:

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;

}

return -(low + 1); // 没有找到不是直接返回负一,返回一个特定的负数

}

5、Arrays.fill() 方法

用指定的值填充数组,如果想要将一个数组的所有元素都是设置为某个值的话,可以使用这个方法。

1)使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[] arr = new int[10];

Arrays.fill(arr, 2333);

System.out.println(Arrays.toString(arr));

}

}

运行结果:

6、Arrays.equals()

Arrays.equals() 方法用于比较两个一维数组是否相等。

1)使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[] array1 = {1, 2, 3};

int[] array2 = {1, 2, 3};

int[] array3 = {1, 2, 4};

// 比较相同的数组

boolean isEqual1 = Arrays.equals(array1, array2);

System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true

// 比较不同的数组

boolean isEqual2 = Arrays.equals(array1, array3);

System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false

}

}

运行结果:

7、Arrays.deepEquals()

Arrays.deepEquals() 方法用于比较两个多维数组是否相等。它会递归地比较数组的每个元素。如果使用 Arrays.equals() 方法的话,则只会比较每一个低一维数组的引用是否相等。

1)使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[][] array1 = {{1, 2, 3}, {4, 5, 6}};

int[][] array2 = {{1, 2, 3}, {4, 5, 6}};

int[][] array3 = {{1, 2, 3}, {4, 5, 7}};

// 比较相同的二维数组

boolean isEqual1 = Arrays.deepEquals(array1, array2);

System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true

// 比较不同的二维数组

boolean isEqual2 = Arrays.deepEquals(array1, array3);

System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false

}

}

运行结果:

2)对比 Arrays.equals() 方法

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[][] array1 = {{1, 2, 3}, {4, 5, 6}};

int[][] array2 = {{1, 2, 3}, {4, 5, 6}};

int[][] array3 = {{1, 2, 3}, {4, 5, 7}};

// 比较相同的二维数组

boolean isEqual1 = Arrays.equals(array1, array2); // 使用 equals()

System.out.println("array1 和 array2 相等? " + isEqual1); // 输出: true

// 比较不同的二维数组

boolean isEqual2 = Arrays.equals(array1, array3); // 使用 equals()

System.out.println("array1 和 array3 相等? " + isEqual2); // 输出: false

}

}

运行结果:

8、Arrays.deepToString()

Arrays.deepToString() 方法用于返回多维数组的字符串表示。如果使用 Arrays.toString() 方法则会返回低一维数组的引用值的数组。

1)使用示例

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[][] array = {{1, 2, 3}, {4, 5, 6}};

// 获取并打印数组的字符串表示

String arrayString = Arrays.deepToString(array);

System.out.println("数组的字符串表示: " + arrayString); // 输出: [[1, 2, 3], [4, 5, 6]]

}

}

运行结果:

2)对比 Arrays.toString() 方法

import java.util.Arrays;

public class Example {

public static void main(String[] args) {

int[][] array = {{1, 2, 3}, {4, 5, 6}};

// 获取并打印数组的字符串表示

String arrayString = Arrays.toString(array); // 使用 toString()

System.out.println("数组的字符串表示: " + arrayString); // 输出: [[1, 2, 3], [4, 5, 6]]

}

}

运行结果:

9、Arrays.asList()

Arrays.asList() 方法是 Java 中的一个静态方法,属于 java.util.Arrays 类。它可以将指定的数组转换为一个固定大小的列表(List)。这个方法返回一个 List 的视图,修改该列表会影响原始数组,反之亦然。

1)使用示例

将数组转换为 List:

import java.util.Arrays;

import java.util.List;

public class Example {

public static void main(String[] args) {

String[] fruitsArray = {"Apple", "Banana", "Cherry"};

// 使用 Arrays.asList 将数组转为列表

List fruitsList = Arrays.asList(fruitsArray);

// 打印列表

System.out.println("水果列表: " + fruitsList); // 输出: 水果列表: [Apple, Banana, Cherry]

}

}

运行结果:

修改列表的元素,数组的元素也会变化:

import java.util.Arrays;

import java.util.List;

public class Example {

public static void main(String[] args) {

Integer[] numbersArray = {1, 2, 3, 4, 5};

// 转换为列表

List numbersList = Arrays.asList(numbersArray);

// 修改列表中的元素

numbersList.set(0, 10);

// 打印修改后的列表和数组

System.out.println("修改后的列表: " + numbersList); // 输出: 修改后的列表: [10, 2, 3, 4, 5]

System.out.println("修改后的数组: " + Arrays.toString(numbersArray)); // 输出: 修改后的数组: [10, 2, 3, 4, 5]

}

}

运行结果:

2)不能使用添加元素

import java.util.Arrays;

import java.util.List;

public class Example {

public static void main(String[] args) {

String[] colorsArray = {"Red", "Green", "Blue"};

// 转换为列表

List colorsList = Arrays.asList(colorsArray);

// 尝试添加新元素(会抛出 UnsupportedOperationException)

try {

colorsList.add("Yellow");

} catch (UnsupportedOperationException e) {

System.out.println("无法添加元素到列表: " + e.getMessage());

}

}

}

运行结果:

这是因为我们使用 Arrays.asList() 方法将数组转换为 List 时,返回的列表是一个基于原始数组的固定大小的视图。这意味着:

固定大小:返回的 List 的大小是固定的,因为原数组的大小是固定的。换句话说,您不能向该列表中添加或删除元素,因为这会导致列表的大小发生变化。当尝试调用 add() 或 remove() 方法来修改列表的大小时,会抛出 UnsupportedOperationException。因为 Arrays.asList() 返回的列表并不支持这些操作。


回顾《全民奇迹》开发史
2020年足球重要赛事—2020年足球赛事一览表