数组实用程序类 - 一口 Java
Billy Korando 于 2023 年 5 月 1 日
当需要比较、复制或排序数组时,开发人员的第一反应可能是写出循环、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
提供了多种方法将数组转换为不同类型,包括 List
、Stream
、Spliterator
和 String
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
在上面的示例中,numbers
和 copyOfNumbers
具有相同的值,但 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
延伸阅读
编程愉快!