0%

数组

Java 数组详解:基础结构与核心操作

数组是 Java 中最基础的数据结构之一,用于存储相同数据类型的元素集合。其核心特点是固定长度随机访问(通过索引快速定位元素),是许多高级集合类(如 ArrayList)的底层存储结构。本文将从数组的初始化、多维数组、特性及应用场景等方面,全面解析 Java 数组的本质。

数组的基本概念

  • 定义:数组是相同数据类型元素的有序集合,每个元素通过唯一索引(下标)访问,索引从 0 开始。
  • 本质:数组在内存中是连续的存储空间,因此支持 O(1) 时间复杂度的随机访问。
  • 长度固定:数组一旦初始化,长度不可修改(若需动态调整,需手动复制到新数组)。

一维数组的初始化

数组的初始化分为静态初始化动态初始化,核心区别在于是否在初始化时直接指定元素值。

静态初始化

初始化时直接为每个元素赋值,数组长度由元素个数自动确定。

语法:
1
2
3
4
5
6
// 方式1:简化语法(声明时直接赋值)
数据类型[] 数组名 = {元素1, 元素2, ..., 元素n};

// 方式2:完整语法(可用于声明后赋值)
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1, 元素2, ..., 元素n};
示例:
1
2
3
4
5
6
// 静态初始化整数数组
int[] numbers = {1, 2, 3, 4};

// 静态初始化字符串数组(声明后赋值)
String[] names;
names = new String[]{"Alice", "Bob", "Charlie"};

动态初始化

初始化时仅指定数组长度,系统为元素分配默认值,后续再手动赋值。

语法:
1
数据类型[] 数组名 = new 数据类型[长度];
系统默认值规则:
  • 基本类型:
    • 整数类型(byteshortintlong)→ 0
    • 浮点类型(floatdouble)→ 0.0
    • 布尔类型(boolean)→ false
    • 字符类型(char)→ '\u0000'(空字符)
  • 引用类型(如 String、对象)→ null
示例:
1
2
3
4
5
6
7
8
9
// 动态初始化整数数组(长度为3,默认值为0)
int[] scores = new int[3];
scores[0] = 90; // 手动为第一个元素赋值
scores[1] = 85;
scores[2] = 95;

// 动态初始化对象数组(默认值为null)
Object[] objects = new Object[2];
objects[0] = new Object(); // 手动赋值

数组的访问与遍历

  • 访问元素:通过 数组名[索引] 访问,如 numbers[0] 表示第一个元素。
  • 遍历元素:使用 for 循环或增强 for 循环(for-each)。
1
2
3
4
5
6
7
8
9
10
11
12
int[] numbers = {1, 2, 3, 4};

// 普通for循环(可修改元素)
for (int i = 0; i < numbers.length; i++) { // length为数组长度属性
System.out.println("索引" + i + ":" + numbers[i]);
numbers[i] *= 2; // 修改元素值
}

// 增强for循环(仅用于读取,无法修改元素)
for (int num : numbers) {
System.out.println("元素:" + num);
}

多维数组

Java 中的多维数组本质是 “数组的数组”,即数组中的元素仍是数组。最常用的是二维数组,可理解为 “表格”(行 + 列),但支持 “非矩形” 结构。

二维数组的静态初始化

直接指定每个 “子数组” 的元素,子数组长度可不同(非矩形数组)。

语法:
1
2
3
4
5
// 方式1:简化语法
数据类型[][] 数组名 = {{元素1, 元素2}, {元素3}, ...};

// 方式2:完整语法
数据类型[][] 数组名 = new 数据类型[][]{{元素1, 元素2}, {元素3}, ...};
示例:
1
2
3
4
5
// 矩形数组(每行长度相同)
int[][] matrix1 = {{1, 2}, {3, 4}, {5, 6}};

// 非矩形数组(每行长度不同)
int[][] matrix2 = {{1}, {2, 3}, {4, 5, 6}};

二维数组的动态初始化

分两种情况:指定行数和列数(矩形数组),或仅指定行数(后续手动定义每行长度,非矩形数组)。

语法:
1
2
3
4
5
6
7
8
// 1. 矩形数组(指定行数和列数)
数据类型[][] 数组名 = new 数据类型[行数][列数];

// 2. 非矩形数组(先指定行数,再定义每行长度)
数据类型[][] 数组名 = new 数据类型[行数][];
数组名[0] = new 数据类型[列数1];
数组名[1] = new 数据类型[列数2];
...
示例:
1
2
3
4
5
6
7
8
9
10
11
// 1. 动态初始化矩形数组(3行2列)
int[][] rectMatrix = new int[3][2];
rectMatrix[0][0] = 1;
rectMatrix[0][1] = 2;
// ... 其余元素默认值为0

// 2. 动态初始化非矩形数组(3行,每行长度分别为1、2、3)
int[][] irregularMatrix = new int[3][];
irregularMatrix[0] = new int[1]; // 第1行长度1
irregularMatrix[1] = new int[2]; // 第2行长度2
irregularMatrix[2] = new int[3]; // 第3行长度3

二维数组的遍历

需使用嵌套循环,外层循环遍历 “行”,内层循环遍历 “列”。

1
2
3
4
5
6
7
8
9
10
int[][] matrix = {{1, 2}, {3, 4, 5}, {6}};

// 遍历所有元素
for (int i = 0; i < matrix.length; i++) { // matrix.length 为行数
int[] row = matrix[i]; // 获取第i行的子数组
for (int j = 0; j < row.length; j++) { // row.length 为当前行的列数
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // 换行
}
输出:
1
2
3
1 2 
3 4 5
6

数组的核心特性

  1. 长度固定:初始化后 length 属性不可修改,若需动态扩容,需通过 Arrays.copyOf 复制到新数组。

    1
    2
    3
    int[] numbers = {1, 2, 3};
    // 扩容为原长度的2倍
    numbers = Arrays.copyOf(numbers, numbers.length * 2); // 结果:[1, 2, 3, 0]
  2. 类型一致性:数组中的元素必须是相同类型(或其子类型,如 Object[] 可存储任何对象)。

  3. 随机访问高效:通过索引访问元素的时间复杂度为 O(1),优于链表(O(n))。

  4. 引用传递:数组是引用类型,赋值操作传递的是内存地址(修改一个变量会影响其他引用)。

    1
    2
    3
    4
    int[] a = {1, 2};
    int[] b = a;
    b[0] = 100;
    System.out.println(a[0]); // 输出100(a和b指向同一数组)
  5. 支持克隆:通过 clone() 方法创建数组的浅拷贝(基本类型复制值,引用类型复制地址)。

    1
    2
    3
    4
    int[] a = {1, 2};
    int[] b = a.clone();
    b[0] = 100;
    System.out.println(a[0]); // 输出1(a和b是不同数组)

数组的应用场景

  1. 底层存储ArrayListHashMap 等集合类底层使用数组存储数据,利用其随机访问优势。
  2. 批量数据处理:如统计分数、存储批量配置等。
  3. 算法实现:排序(如快速排序、冒泡排序)、查找(如二分查找)等算法多基于数组实现。
  4. 矩阵运算:二维数组可表示矩阵,用于数学计算、图像处理等领域

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10