Java Array 数组

Java 中的 Array 是一种用于存储固定大小相同类型元素的数据结构。Array 可以存储基本数据类型(如 int、float、double 等)和对象类型(如 String、Person 等)。

Java 数组

Array 特点

Java 中的 Array 有以下特点:

  1. 长度固定:Array 的长度在创建时就已经确定,并且不能被修改,但是可以指向其他数组。
  2. 同类型元素:Array 中的所有元素必须是同一种类型(对象类型存储的是引用)。
  3. 内存连续:Array 存储在连续的内存位置。
  4. 下标从 0 开始:Array 中的元素是通过下标来访问的,下标从 0 开始,最大下标为长度减 1。
  5. 给定数组下标访问下标对应的元素时,的时间复杂度为 1。
  6. Array 是Java 中的对象,因此可以使用对象属性 lenght 获取到 Array 的长度。
  7. Java 中 Array 都实现了 Cloneablejava.io.Serializable 接口。

Array 创建

Java 中的 Array 可以通过以下方式创建:

数组定义语法:type[] name; 或者 type name[];

  1. 使用 new 关键字:可以使用 new 关键字来创建一个指定长度的 Array,使用 new 关键字创建数组需要指定数组的长度。:
int[] arr = new int[2];
String[] strArr = new String[5];
  1. 使用大括号初始化:可以使用大括号来初始化 Array 的元素,可以在创建时直接直接每个元素的信息。例如,下面的代码创建了一个包含 3 个元素的 String 类型 Array:
String[] arr = { "Hello", "world", "!" };

Array 访问

Java 中的每一项成为元素,可以通过下标来访问或者修改 Array 中的元素。例如,下面的代码访问了数组的第一个元素,输出它的值是 10:

int[] arr = new int[2];
arr[0] = 10;
arr[1] = 20;
System.out.println(arr[0]);
// 输出:10

除了指定下标来访问数组中的某一个元素外,还可以使用循环来访问每一个元素。

int[] arr = {1, 2, 3};
for (int a : arr) {
    System.out.println(a);
}// 输出:1  2  3
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}// 输出:1  2  3

数组是不能直接打印输出的,如果你直接打印一个数组,会得到一个内存地址:

int[] arr = {1, 2, 3};
System.out.println(arr); // 数组地址
// 输出:[I@4b1210ee

输出 Array 的大小。

int[] arr = {1,2,3};
System.out.println(arr.length);
// 输出: 3

Array 复制

Cloneable

Java 中的数组实现了 Cloneable 方法,所以可以直接复制。

String[] strArr = {"hello", "world", "!"};
String[] strArrByClone = strArr.clone();
System.out.println(String.join(" ", strArrByClone));
// 输出:hello world !

对于元素为引用类型的数组,复制也是如此。

class Person{
    public String name;
    public Person(String name) {
        this.name = name;
    }
}

测试可见对新数组的第一个元素进行修改,不会影响到老数组的第一个元素,可见这是一个深拷贝。

// 测试
Person[] personArr = new Person[2];
personArr[0] = new Person("www");
personArr[1] = new Person("wdbyte.com");
Person[] personArrByClone = personArr.clone();
personArrByClone[0] = new Person("https://www");
System.out.println(personArr[0].name);// 输出:www
System.out.println(personArrByClone[0].name); // 输出:https://www

注意:clone 对于多维数组的拷贝,只会进行浅拷贝。

Person[][] personArr = new Person[2][2];
personArr[0][0] = new Person("www");
personArr[0][1] = new Person("wdbyte.com");
Person[][] personArrByClone = personArr.clone();
personArrByClone[0][0] = new Person("https://www");
System.out.println(personArr[0][0].name); // 输出:https://www
System.out.println(personArrByClone[0][0].name); // 输出:https://www

System.arraycopy

使用 System.arraycopy 复制数组,下面的操作的意思是,从 strArr 数组中下标为 1 的元素开始复制到 strAyyByCopy 数组中,复制的元素的个数为两个。

String[] strArr = {"hello", "world", "!"};
String[] strAyyByCopy = new String[5];
System.arraycopy(strArr,1,strAyyByCopy,3,2);
for (String s : strAyyByCopy) {
    System.out.println(s);
}
// 输出:null
// null
// null
// world
// !

Arrays.copyOfRange

使用 Arrays.copyOfRange 复制数组,下面的意思是拷贝 strArr 数组中的从第 0 个到第 2 个元素之间的元素。

注意:这个范围包含左边的第 0 个元素,但是不包含右边的第 2 个元素。

String[] strArr = {"hello", "world", "!"};
//
String[] newArr = Arrays.copyOfRange(strArr, 0, 2);
System.out.println(Arrays.toString(newArr));
// 输出:[hello, world]

Array 操作

Java 中的 Arrays 类提供了一系列用于操作数组的静态方法。以下是 Arrays 常用的操作方法:

方法名 描述
sort() 对数组进行排序
parallelSort() 并行排序数组
binarySearch() 对已排序的数组进行二分查找
equals() 比较两个数组是否相等
fill() 将数组的所有元素都赋为指定的值
toString() 将数组转换成字符串输出
copyOf() 复制数组
asList() 将数组转换成 List

这些方法可以帮助我们更方便地操作数组,提高编码效率。

下面是几个方法的使用演示:

  1. 创建数组,排序数组,输出数组

    int[] numArr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
    // 对数组进行排序
    Arrays.sort(numArr);
    // 将数组转换成字符串输出
    System.out.println(Arrays.toString(numArr));
    // 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
  2. 创建数组,为数组的每个元素赋值。

    String[] strArray = new String[3];
    // 将数组的所有元素都赋为指定的值
    Arrays.fill(strArray,"byte");
    System.out.println(Arrays.toString(strArray));
    // 输出:[byte, byte, byte]
    
  3. 将数组转换成 List。

    // 将数组转换成 List
    List<String> stringList = Arrays.asList("a","b","c");
    System.out.println(stringList);
    // 输出:
    [a, b, c]
    

常见问题

由于数组的长度固定,而访问数组中的元素需要指定下标,那么如果指定的下标超出了数组的长度会发生什么呢?

当尝试访问数组中不存在的元素时,就会抛出ArrayIndexOutOfBoundsException 异常,用于表示访问数组时下标越界的情况。

例如,如果一个数组长度为5,但是你尝试访问下标为5 的元素,就会抛出 ArrayIndexOutOfBoundsException 异常。

该异常属于运行时异常(unchecked exception),不需要显式地捕获或声明,但是如果不处理这个异常,程序就会崩溃。因此,在访问数组时,应该始终确保访问的下标在数组的有效范围内。

以下是一个抛出 ArrayIndexOutOfBoundsException 异常的示例代码:

int[] arr = new int[5];
arr[5] =10; // 下标越界,抛出 ArrayIndexOutOfBoundsException 异常

数组还有一下其他特殊数组,比如多维数组,锯齿数组等,可以在下面的文章中看到。

参考:Oracle Java Arrays 教程

一如既往,文章中代码存放在 Github.com/niumoo/javaNotes.