Java中的数组是一种基础且强大的数据结构,用于存储固定大小的同类型元素。下面这个表格汇总了它的核心特性,帮助你快速建立整体印象。
特性类别 | 具体内容 |
基本定义 | 相同类型数据的有序集合 |
长度特性 | 一旦创建,长度固定且不可变 |
元素类型 | 所有元素必须是相同类型(基本类型或引用类型) |
内存分配 | 在堆内存中分配,元素内存地址连续 |
访问方式 | 通过索引(下标)访问,索引从0开始 |
核心优点 | 随机访问效率极高(时间复杂度O(1)) |
主要缺点 | 长度不可变;随机插入/删除元素效率低 |
💡 从基础到应用
🧱 声明与初始化
声明数组时,推荐将方括号紧挨数据类型,这更清晰地表明变量是“某类型的数组” 。
// 推荐的声明方式
int[] numbers;
String[] names;
初始化主要有两种方式:
- 静态初始化:声明的同时直接指定元素值。
int[] primes = {2, 3, 5, 7, 11}; // 数组长度根据大括号内元素个数自动确定
- 动态初始化:声明时指定数组长度,系统为元素赋默认值。
int[] scores = new int[5]; // 创建一个长度为5的整型数组,所有元素初始值为0
scores[0] = 95; // 然后再为各个元素赋值
不同数据类型的默认值如下:
- 数值类型(如
int
,double
):0
或0.0
boolean
类型:false
- 字符类型(
char
):'\u0000'
(空字符) - 引用类型(如
String
, 自定义对象):null
⛓️ 内存模型与边界
数组是引用类型。变量(如numbers
)存储在栈内存,它持有的是数组对象在堆内存中的地址。真正的数组对象在堆中分配,其元素在内存中是连续存储的,这是数组能实现高效随机访问的根本原因 。
访问数组时,索引必须在 [0, array.length - 1]
范围内。如果越界(例如访问array[array.length]
),Java运行时环境会抛出 ArrayIndexOutOfBoundsException
异常,这是最常见的错误之一 。
🔄 遍历与拷贝
- 遍历数组:可以使用基本的
for
循环(通过索引)或更简洁的增强for循环(for-each循环)。
int[] arr = {10, 20, 30};
// 基本for循环
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 增强for循环 (直接遍历元素,无需索引)
for (int value : arr) {
System.out.println(value);
}
- 数组拷贝:需要区分"引用拷贝"和"内容拷贝"。直接赋值 (
int[] newArr = arr;
) 只是让新变量指向原数组,修改会相互影响。要实现真正的独立副本,常用方法有Arrays.copyOf()
和System.arraycopy()
。
import java.util.Arrays;
int[] original = {1, 2, 3};
int[] copy = Arrays.copyOf(original, original.length); // 内容拷贝
copy[0] = 99; // 修改副本不会影响原数组
System.out.println(original[0]); // 输出仍是 1
🌐 多维数组
Java支持多维数组,最常见的是二维数组,可理解为“数组的数组”或表格 。其声明、初始化和遍历示例如下:
// 静态初始化一个二维数组(矩阵)
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 动态初始化一个3行4列的二维数组
String[][] table = new String[3][4];
// 遍历二维数组(嵌套循环)
for (int i = 0; i < matrix.length; i++) { // 遍历行
for (int j = 0; j < matrix[i].length; j++) { // 遍历当前行的列
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
需要注意的是,多维数组中每个子数组的长度可以不同,这被称为不规则数组(Jagged Array)。
int[][] jaggedArray = new int[3][]; // 只指定行数
jaggedArray[0] = new int[2]; // 第一行有2列
jaggedArray[1] = new int[3]; // 第二行有3列
jaggedArray[2] = new int[4]; // 第三行有4列
🛠️ 工具类 Arrays
java.util.Arrays
类提供了大量静态方法,用于操作数组,非常方便 。
- 排序:
Arrays.sort(array)
对数组进行升序排序(修改原数组)。 - 二分查找:
Arrays.binarySearch(array, key)
在已排序的数组中高效查找元素,返回索引。 - 比较:
Arrays.equals(array1, array2)
比较两个数组内容是否相等。 - 填充:
Arrays.fill(array, value)
将数组所有元素设置为指定值。 - 转换为字符串:
Arrays.toString(array)
将数组内容转换为美观的字符串格式,便于打印调试。
int[] arr = {5, 3, 9, 1};
System.out.println(Arrays.toString(arr)); // 输出: [5, 3, 9, 1]
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // 输出: [1, 3, 5, 9]
int index = Arrays.binarySearch(arr, 5);
System.out.println(index); // 输出: 2
💎 总结与使用建议
数组因其内存连续和固定长度的特性,在随机访问场景下性能极高。但在需要频繁插入、删除元素或动态调整大小时,效率较低 。
在实际开发中:
- 若数据量已知且固定,且操作以查询为主,数组是很好的选择。
- 若需要动态扩容或频繁进行结构性修改(插入、删除),应考虑使用
ArrayList
等集合框架中的类。
希望这份详细的介绍能帮助你全面理解Java中的数组。如果你对特定应用场景或更深入的话题(如与集合类的详细对比)有进一步兴趣,我们可以继续探讨。