数组实用程序类 - 一口 Java

当需要比较、复制或排序数组时,开发人员的第一反应可能是写出循环、if 语句以及处理此操作所需的其他逻辑。在大多数情况下,这都是一个错误,因为它会重复 java.util.Arrays 实用程序类中可用的行为。我们来看看如何使用 Arrays 类来处理数组上的日常操作。

数组历史

java.util.Arrays 于 JDK 2 中添加到 JDK 中,所以已经有一段时间了。它在后续版本中经历了多次更新。最重要的更新是在 JDK 8 中;最近的更新是在 JDK 9 中。因此,如果你仍在使用 JDK 8,可能有一些你不太熟悉的更改。

复制数组

Arrays 提供了使用 copy(T[], int length) 复制数组的多个选项。

int[] numbers = new int[] {1,2,3,4,5};
int[] copyOfNumbers = Arrays.copyOf(numbers, numbers.length);
int[] copyOfSomeNumbers = Arrays.copyOf(numbers, numbers.length - 3);
int[] copyOfNumbersWithPadding = Arrays.copyOf(numbers, numbers.length + 1);
  • copyOfNumbers - 是简单复制数组的一个示例。

  • copyOfSomeNumbers - 是仅复制数组一部分的示例。

  • copyOfNumbersWithPadding - 是复制数组并添加填充的示例。填充值是该类型的默认值;对于 int,该值为 0。

复制子范围

Arrays 还提供了一个选项,用于使用 copyOfRange(T[]. int startIndex, int endIndex) 从数组中复制特定子范围,如下面的示例所示

int[] numbers = new int[] {1,2,3,4,5};
int[] copyOfNumbers = Arrays.copyOfRange(numbers, 0, 3);
	
System.out.println(Arrays.toString(numbers));//1,2,3,4,5
System.out.println(Arrays.toString(copyOfNumbers));//1,2,3

将数组转换为其他类型

Arrays 提供了多种方法将数组转换为不同类型,包括 ListStreamSpliteratorString

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

Arrays.asList(numbers);
Arrays.stream(numbers);
Arrays.spliterator(numbers);
Arrays.toString(numbers);

比较数组

对于比较数组,Arrays 提供了多种选项,通常提供比默认选项更好的结果。我们来看看

int[] numbers = new int[] {1,2,3,4,5};
int[] copyOfNumbers = Arrays.copyOf(numbers, 5);
	
System.out.println(numbers.equals(copyOfNumbers));//False
System.out.println(Arrays.equals(numbers, copyOfNumbers));//True

在上面的示例中,numberscopyOfNumbers 具有相同的值,但 int[].equals(int[]) 返回可能意外的 false。这是因为它按引用比较,而不是按值比较。而 Arrays.equals(T[]) 根据存储在数组中的值比较两个数组。

比较子范围

与复制类似,Arrays 还有一个选项,用于比较数组的子范围,如下面的示例所示

int[] numbers = new int[] { 1, 2, 3, 4, 5 };
int[] moreNumbers = new int[] { 1, 2, 3, 6, 7 };

System.out.println(numbers.equals(moreNumbers));// False
System.out.println(Arrays.equals(numbers, moreNumbers));// False
System.out.println(Arrays.equals(numbers, 0, 2, moreNumbers, 0, 2));// True

深度比较

使用嵌套/多维数组时,有 deepEquals(T[]),它可以逐步比较数组和任何嵌套数组

int[][] coordinates = new int[][] { {10,20}, {100,200} };
int[][] altCoordinates = new int[][] { {10,20}, {100,200} };
	
System.out.println(coordinates.equals(altCoordinates));//False
System.out.println(Arrays.equals(coordinates, altCoordinates));//False
System.out.println(Arrays.deepEquals(coordinates, altCoordinates));//True

比较可比较数组

Arrays 还允许比较包含基本值和类型(实现 Comparable<T>)的数组,方法是使用 compare(T[], T[])

int[] littleNumbers = new int[] {10, 20};
int[] copyOfLittleNumbers = Arrays.copyOf(littleNumbers, 2);
int[] bigNumbers = new int[] {100, 200};
	
System.out.println(Arrays.compare(littleNumbers, bigNumbers));//-1
System.out.println(Arrays.compare(bigNumbers, littleNumbers));//1
System.out.println(Arrays.compare(littleNumbers, copyOfLittleNumbers));//0

排序数组

对于包含基本值和类型(实现 Comparable<T>)的数组,可以使用 Arrays 使用 sort(T[]) 对数组进行排序。 Arrays 还可以使用 sort(T[], startIndex, endIndex) 仅对数组的一个子范围进行排序。请注意, Arrays 对传递的数组进行排序;它不会返回已排序数组的副本

int[] numbers = new int[] { 3, 5, 2, 1, 4 };
int[] moreNumbers = new int[] { 3, 5, 2, 1, 4 };

System.out.println(Arrays.toString(numbers));// 3,5,2,1,4
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));// 1,2,3,4,5

System.out.println(Arrays.toString(moreNumbers));// 3,5,2,1,4
Arrays.sort(moreNumbers, 0, 3);
System.out.println(Arrays.toString(moreNumbers));// 2,3,5,1,4

搜索数组

对于已排序的数组, Arrays 还提供了一个操作,使用 binarySearch(T[], T key) 搜索它们,如果 key 匹配,则返回索引,如果 key 低于数组的范围,则返回 -1,如果 key 高于范围,则返回数组长度的负值 + 1(即如果数组长度为 5,则返回 -6)。未排序的数组不会返回预期结果。以下是使用 binarySearch(T[], T key) 的示例

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

System.out.println(Arrays.binarySearch(numbers, 4)); // 3 - insertion point in array
System.out.println(Arrays.binarySearch(numbers, -0));// -1 - low value not in array
													 // (one less than 0)
System.out.println(Arrays.binarySearch(numbers, 8)); // -6 - high value not in array
													 // (negative value of length + 1)

其他数组操作

Arrays 提供的还有其他一些操作,本文未涵盖,也值得一试

  • deepHashCode(T[]) - Javadoc
  • deepToString(T[]) - Javadoc
  • fill(T[], T val) - Javadoc
  • hashCode(T[]) - Javadoc
  • mismatch(T[], T[]) - Javadoc
  • parallelSort(T[]) - Javadoc
  • parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator o) - JavaDoc

延伸阅读

Arrays JavaDoc

编程愉快!