Java数组全面解析:从基础到实战应用
一、数组是什么?为什么需要数组?
想象你管理一个班级的50名学生成绩,如果要存储每个学生的数学分数,用50个独立变量score1到score50会非常麻烦。Java数组就是为解决这类问题而生的有序数据容器,它允许我们把多个相同类型的值存储在单个变量中。
数组核心特点:
- 固定长度:创建时确定容量
- 索引访问:通过
[下标]访问元素(从0开始) - 类型统一:只能存储相同数据类型
- 内存连续:元素在内存中连续存储
二、数组使用三部曲
1. 声明与初始化
方式一:静态初始化(适合已知具体值)
// 完整写法
int[] scores = new int[]{90, 85, 78, 93, 64};
// 简写形式
String[] weekDays = {"Mon", "Tue", "Wed", "Thu", "Fri"};
方式二:动态初始化(适合先创建容器后赋值)
double[] temperatures = new double[7]; // 创建7个元素的数组
temperatures[0] = 28.5; // 逐个赋值
temperatures[1] = 30.0;
2. 访问与修改
int[] numbers = {10, 20, 30, 40, 50};
// 访问第三个元素(索引从0开始)
System.out.println(numbers[2]); // 输出30
// 修改第二个元素
numbers[1] = 200;
System.out.println(Arrays.toString(numbers)); // [10, 200, 30, 40, 50]
3. 遍历数组
传统for循环(适合需要索引的场景)
for (int i = 0; i < numbers.length; i++) { // 使用length属性
System.out.println("索引" + i + ": " + numbers[i]);
}
增强for循环(简洁但无法获取索引)
for (int num : numbers) {
System.out.println(num);
}
三、二维数组:数组的数组
// 声明3行4列的二维数组
int[][] matrix = new int[3][4];
// 静态初始化
String[][] chessBoard = {
{"车", "马", "象"},
{"兵", "兵", "兵"},
{"", "", ""}, // 空行
{"卒", "卒", "卒"},
{"俥", "傌", "相"}
};
// 访问第二行第三列的元素
System.out.println(chessBoard[1][2]); // 输出"兵"
四、数组常用操作案例
案例1:学生成绩统计
int[] scores = {85, 92, 76, 88, 95};
// 求最高分
int max = scores[0];
for (int score : scores) {
if (score > max) {
max = score;
}
}
// 计算平均分
double sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
double average = sum / scores.length;
System.out.println("最高分:" + max); // 95
System.out.println("平均分:" + average); // 87.2
案例2:数组排序(冒泡排序)
int[] numbers = {5, 3, 8, 2, 1};
for (int i = 0; i < numbers.length - 1; i++) {
for (int j = 0; j < numbers.length - 1 - i; j++) {
if (numbers[j] > numbers[j+1]) {
// 交换元素
int temp = numbers[j];
numbers[j] = numbers[j+1];
numbers[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(numbers)); // [1, 2, 3, 5, 8]
五、数组 vs ArrayList 对比
| 特性 | 数组 | ArrayList |
|---|---|---|
| 长度 | 固定长度 | 动态扩容 |
| 类型支持 | 支持基本类型和对象 | 只能存储对象 |
| 性能 | 随机访问更快 | 插入删除更方便 |
| 功能方法 | 需要手动实现 | 内置add/remove等方法 |
| 内存占用 | 更小 | 较大(需要维护内部数组) |
| 使用场景 | 数据量固定、追求性能 | 需要频繁增删改 |
选择建议:
- 需要存储基本类型数据 → 优先考虑数组
- 数据量变化频繁 → 选择ArrayList
- 对性能要求极高 → 考虑数组
- 需要丰富的操作方法 → 使用ArrayList
六、常见问题与技巧
1. 数组越界异常
int[] arr = new int[5];
System.out.println(arr[5]); // 抛出ArrayIndexOutOfBoundsException
解决方法:始终使用array.length获取长度,避免硬编码索引值
2. 数组复制
int[] source = {1, 2, 3};
int[] dest = new int[3];
// 方式一:System.arraycopy
System.arraycopy(source, 0, dest, 0, source.length);
// 方式二:Arrays.copyOf
int[] copy = Arrays.copyOf(source, source.length);
3. 快速打印数组内容
// 不要直接打印数组对象
System.out.println(numbers); // 输出类似[I@1b6d3586
// 正确方式
System.out.println(Arrays.toString(numbers)); // [1, 2, 3]
七、Java 8+ 新特性:Stream操作数组
int[] numbers = {2, 4, 6, 8, 10};
// 求平方和
int sumOfSquares = Arrays.stream(numbers)
.map(n -> n * n)
.sum();
// 筛选偶数(实际数组已全是偶数)
int[] evens = Arrays.stream(numbers)
.filter(n -> n % 2 == 0)
.toArray();
结语
数组是Java编程中最基础也是最重要的数据结构之一。尽管在复杂场景下常被集合框架替代,但在性能敏感场景(如游戏开发、大数据处理)中仍不可替代。掌握数组的创建、操作和常用算法,是每个Java开发者的必备技能。建议通过以下步骤巩固学习:
- 手写各种数组排序算法
- 实现矩阵运算(如矩阵转置、相加)
- 尝试用数组实现简单数据结构(如栈、队列)
- 对比数组与其他集合的性能差异
记住,Arrays工具类提供了许多实用方法(排序、二分查找等),在开发中善用这些工具可以事半功倍。