目录
2. Arrays.copyOf(array, length)
4. Arrays.binarySearch(array, Constant)
5. Arrays.fill(array, Constant)
6. Arrays.equals(array1, array2)
7. Arrays.deepEquals(matrix1, matrix2)
8. Arrays.deepToString(matrix)
一、关于动态创建
需要注意的是,java中的数组声明方案实际上是有两个的,传统的方法是:
dataType arrayRefVar[];
这个方法继承了C与C++的衣钵,Java源文档中也特别说明此方案是为方便原C与C++程序员能尽快适应java语言。但是这种方案并不常用,很不“java”。
现在更常用的数组声明方案是:
dataType[] arrayRefVar;
这个方案很像C#,但是其实历史上C#是微软与SUN公司(出品java的公式)闹掰之后自己仿造java创立的语言,所以也许说C#的数组声明的来源正是来自这也说不定。
声明完毕后需要为数组动态分配空间,其中动态分配方法来源于C++的new方法:
dataType[] arrayRefVar = new dataType[arraySize];
这个语句做了什么呢?
- 使用dataType[arraySize]创建了一个数组
- 把创建的数组的引用赋值给变量 arrayRefVar
那么,如果要创建多维数组呢?只需要修改数据类型即可:
dataType[][] arrayRefVar = new dataType[arrayHeight][arrayWidth];
插一句静态创建
最后提一句,动态创建不是唯一的创建方案,数组的静态创建也是常用的,其风格与C语言系列类似,可通过在[ ]写入确定量或者用{ }取等预定元素都是可以的:
dataType[10] arrayRefVar1;
dataType[10][20] arrayRefVar1;
double[] arrayRefVar2 = {1.2, 2.3, 3.4};
二、Arrays 类简介
Arrays 类是 Java 语言中用于操作数组的一个工具类,提供了多种静态方法来处理数组,包括排序、搜索、填充、比较等操作。这个类位于 java.util 包中。
Arrays类的构造方法被设置为私有(private),因此无法创建 Arrays 对象。Arrays 类的所有公有方法都是静态的,可以直接通过类名调用。
三、Arrays 类常用函数介绍
1. Arrays.toString(array)
返回一维数组的字符串表示。
(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(array, length)
复制数组,可以指定新数组长度。
(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]
}
}
也就是说第一个参数是源数组,第二个参数是从源数组中复制多少个元素到新数组中,如果第二个参数大于了源数组的大小,则新数组中大于源数组大小的部分的元素都是类型默认值。
(2)存疑
具体涉及的深拷贝,浅拷贝问题不在这里解答。从原理上讲与 C++ 涉及的是相同的,感兴趣可以自行前往
3. Arrays.sort(array)
(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<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(Arrays.toString(arr));
}
}
这里的数组不能使用基本数据类型,因为这里的 sort() 方法的声明是这样的:
public static <T> void sort(T[] a, Comparator<? super T> c);
这里的 sort 是一个泛型方法,泛型参数只能接受类类型,所以这里需要使用包装类型数组作为第一个参数,对于第二个参数,我们传入的是:
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
这显然是一个匿名内部类,它实现了 Comparator 接口,同时重写了这个接口的 compare() 方法,这个方法是关键,这里返回值是 o2 - o1,这就代表了,如果 o1 如果大于 o2 的话,则返回负值,对于 sort() 方法内部某个地方就是调用的 compare() 方法来比较两个参数的大小。
如果是升序的话,o1 大于 o2 应当返回的是正值,这里返回了负值,所以就是将顺序设置为反的,所以最终可以得到降序的数组。
(3) 相关算法
- 基本类型数组(如 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(array, Constant)
(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(array, Constant)
用指定的值填充数组,如果想要将一个数组的所有元素都是设置为某个值的话,可以使用这个方法。
(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(array1, array2)
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(matrix1, matrix2)
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(matrix)
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(array)
将数组转换为 List:
(1)示例(代码及运行结果)
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<String> 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<Integer> 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<String> 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() 返回的列表并不支持这些操作。
10. else
这里给出一张图片,详细需要请参考具体的库函数。