
数组
数组是相同类型数据的有序集合
数组中的概念
- 数组名
- 下标(或索引)
- 元素
- 数组的长度
⭐数组的特点
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型(每个元素位置存储基本数据类型的值)和引用数据类型(每个元素位置存储对象(本质是存储对象的首地址))。
- 创建数组对象会在内存中开辟一整块连续的空间。占据的空间的大小,取决于数组的长度和数组中元素的类型。
- 数组中的元素在内存中是依次紧密排列的,有序的。
- 数组,一旦初始化完成,其长度就是确定的。数组的长度一旦确定,就不能修改。
- 可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快(即支持随机访问)。
- 数组名中引用的是这块连续空间的首地址。
一维数组
声明
// 推荐
元素的数据类型[] 一维数组的名称;
// 不推荐 C语言写法
元素的数据类型 一维数组的名称[];
int[] arr;
int arr1[];
double[] arr2;
String[] arr3;
声明需要明确:
(1)数组的维度:在Java中数组的符号是[],[]表示一维,[][]表示二维。
(2)数组的元素类型:即创建的数组容器可以存储什么数据类型的数据。元素的类型可以是任意的Java的数据类型。例如:int、String、自定义的类等。
(3)数组名:数组的标识符,数组名其实也是变量名,按照变量的命名规范来命名。数组名是个引用数据类型的变量,因为它代表一组数据。
Java语言中声明数组时不能指定其长度(数组中元素的个数)。
// 如下错误
int a[5];
int arr[5] = {1, 2, 3, 4, 5};
初始化
静态初始化
-
如果数组变量的初始化和数组元素的赋值操作同时进行,那就称为静态初始化。
-
静态初始化,本质是用静态数据(编译时已知)为数组初始化。此时数组的长度由静态数据的个数决定。
-
new:关键字,创建数组使用的关键字。因为数组本身是引用数据类型,所以要用 new 创建数组实体。
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...};
//或
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...};
//或
数据类型[] 数组名 = {元素1,元素2,元素3...}; // 必须在一个语句中完成,不能分成两个语句写
int[] arr = new int[]{1, 2, 3, 4, 5};
//or
int[] arr;
arr = new int[]{1, 2, 3, 4, 5};
//or
int[] arr = {1, 2, 3, 4, 5};
//如下错误
int[] arr;
arr = {1, 2, 3, 4, 5};
动态初始化
数组变量的初始化和数组元素的赋值操作分开进行,即为动态初始化。
动态初始化中,只确定了元素的个数(即数组的长度),而元素值此时只是默认值,真正期望的数据需要后续单独一个一个赋值。
数组存储的元素的数据类型[] 数组名字 = new 数组存储的元素的数据类型[长度];
//或
数组存储的数据类型[] 数组名字;
数组名字 = new 数组存储的数据类型[长度];
- 数组的长度,表示数组容器中可以最多存储多少个元素。注意:数组长度一旦指定,不可更改。
int[] arr = new int[5];
int[] arr;
arr = new int[5];
//如下错误
int[] arr = new int[5]{1, 2, 3, 4, 5}; // 后面有{}指定元素列表,就不需要在[]中指定元素个数
- 数组是引用类型,当使用动态初始化方式创建数组时,元素值只是默认值。例如:
int a[]= new int[5];
System.out.println(a[3]); //a[3]的默认值为0
对于基本数据类型而言,默认初始化值各有不同。
对于引用数据类型而言,默认初始化值为 null(🌟注意与0不同)
| 数组元素类型 | 元素默认值 |
|---|---|
| byte | 0 |
| short | 0 |
| int | 0 |
| long | 0L |
| float | 0.0F |
| double | 0.0 |
| char | 0 或写为 \u0000 |
| boolean | false |
| 引用类型 | null |
使用
- 数组的元素总个数,即数组的长度。每个数组都有一个属性 length 指明它的长度。每个数组都具有长度,而且一旦初始化,其长度就是确定,且是不可变的。
- 可以通过数组的索引/下标访问到数组中的元素。格式:数组名[索引/下标]。数组的下标从[0]开始,下标范围是[0, 数组的长度-1],即[0, 数组名.length-1]。数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
int[] arr = {1, 2, 3, 4, 5};
System.out.println("arr数组的长度:" + arr.length);
System.out.println("arr数组的第1个元素:" + arr[0]); //下标从0开始
//修改第1个元素的值
arr[0] = 100;
//遍历
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
for (int x : arr) {
System.out.println(x);
}
public static void main(String[] args) {
// 定义数组,存储3个元素
int[] arr = new int[3];
//数组索引进行赋值
arr[0] = 5;
arr[1] = 6;
arr[2] = 7;
//输出3个索引上的元素值
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
//定义数组变量arr2,将arr数组的首地址赋值给arr2
//⭐引用类型,指向同一个数组
int[] arr2 = arr;
arr2[1] = 9;
System.out.println(arr[1]); //9
}
多维数组
多维数组其实是 “数组的数组”。
int[][] arr = new int[3][4];
实际上是:
arr是一个长度为 3 的数组;- 每个元素
arr[i]又是一个长度为 4 的int数组。
Java 的多维数组 不要求每一行长度相同(即“非规则数组”是允许的),这与 C/C++ 不同。
声明
//推荐
int[][] arr;
// 不推荐
int arr[][];
int[] arr[];
int[] x, y[];
// x是一维数组,y是二维数组
静态初始化
int[][] arr = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[][] arr = new int[][] {
{1, 2},
{3, 4, 5},
{6}
};
int[][] arr;
arr = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9, 10}};
arr = new int[3][3]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9, 10}}; //错误,静态初始化右边new数据类型[][]中不能写数字
动态初始化
int[][] arr = new int[3][4]; // 3行4列
//此时每个元素都被初始化为默认值 0。
int[][] arr = new int[3][]; // 3行,但每行长度不定
//此时只是确定了总行数,每一行里面现在是null
arr[0] = new int[2];
//此时已经new完的行的元素就有默认值了,没有new的行还是null
arr[1] = new int[4];
arr[2] = new int[3];
int[][] arr = new int[][3]; //错误
使用
arr[0][1] = 10;
System.out.println(arr[0][1]);
System.out.println(arr.length); // 行数
System.out.println(arr[0].length); // 第0行的列数
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
for (int[] row : arr) {
for (int val : row) {
System.out.print(val + " ");
}
System.out.println();
}
数组常见异常
- ArrayIndexOutOfBoundsException(数组下标越界异常)
当程序试图访问数组中不存在的索引位置(即索引小于0或大于等于数组长度)时,就会抛出这个异常。
int[] nums = {1, 2, 3};
System.out.println(nums[3]); // 错误:索引3不存在
- NullPointerException(空指针异常)
当数组变量没有指向任何有效的内存空间(即值为 null),而程序却试图访问该数组时,就会抛出此异常。
int[] nums = null;
System.out.println(nums.length); // 错误:nums未初始化
数组工具类:java.util.Arrays
java.util.Arrays 是 Java 提供的一个非常常用的数组工具类,位于 java.util 包中,主要用于操作数组(如排序、查找、比较、填充、转换等)。它提供了许多静态方法,简化了对数组的操作。
排序方法:sort()
对数组元素进行升序排序(默认使用自然顺序)。
int[] nums = {5, 3, 8, 1};
Arrays.sort(nums);
System.out.println(Arrays.toString(nums)); // [1, 3, 5, 8]
// 对对象数组按自定义规则排序(使用 Comparator)
String[] names = {"Tom", "Jerry", "Alice"};
Arrays.sort(names, (a, b) -> b.compareTo(a)); // 按字母逆序
System.out.println(Arrays.toString(names)); // [Tom, Jerry, Alice]
二分查找:binarySearch()
使用二分查找算法查找元素的索引。⚠️ 使用前必须先排序。
int[] arr = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(arr, 5);
System.out.println(index); // 输出 2
比较方法:equals()、deepEquals()
比较两个数组内容是否相等。
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(Arrays.equals(a, b)); // true
Object[] arr1 = { new int[]{1, 2}, new int[]{3, 4} };
Object[] arr2 = { new int[]{1, 2}, new int[]{3, 4} };
System.out.println(Arrays.deepEquals(arr1, arr2)); // true(深层比较)
填充方法:fill()
将数组的所有元素或部分元素填充为指定值。
int[] arr = new int[5];
Arrays.fill(arr, 7);
System.out.println(Arrays.toString(arr)); // [7, 7, 7, 7, 7]
转字符串方法:toString()、deepToString()
将数组内容转换为字符串,方便打印。
int[] nums = {1, 2, 3};
System.out.println(Arrays.toString(nums)); // [1, 2, 3]
Object[] arr = { new int[]{1, 2}, new int[]{3, 4} };
System.out.println(Arrays.deepToString(arr)); // [[1, 2], [3, 4]]
拷贝方法:copyOf()、copyOfRange()
用于复制数组或数组的一部分。
int[] a = {1, 2, 3, 4};
int[] b = Arrays.copyOf(a, 2); // [1, 2]
int[] c = Arrays.copyOfRange(a, 1, 3); // [2, 3]
并行排序(Java 8):parallelSort()
Java 8 引入的多线程排序方法,适用于大数组。
int[] arr = {5, 3, 8, 1, 9};
Arrays.parallelSort(arr);
System.out.println(Arrays.toString(arr)); // [1, 3, 5, 8, 9]
生成流(Java 8):stream()
将数组转换为 Stream,便于使用 Stream API。
int[] nums = {1, 2, 3, 4};
int sum = Arrays.stream(nums).sum();
System.out.println(sum); // 10
比较与哈希方法(Java 9)
compare(a, b):按字典序比较两个数组。mismatch(a, b):返回第一个不匹配元素的索引。hashCode(a)、deepHashCode(a):生成哈希值。
int[] a = {1, 2, 3};
int[] b = {1, 2, 4};
System.out.println(Arrays.compare(a, b)); // <0 (a < b)
System.out.println(Arrays.mismatch(a, b)); // 2
2925

被折叠的 条评论
为什么被折叠?



