🔥 前言
"学 Java 的时候,我一直以为数组就是简单的容器,直到写了一个需要处理大量数据的程序,才发现数组的重要性。如果没有数组,处理多个同类型数据时只能创建无数个变量,代码会变得极其臃肿。"
今天这篇,我把 Java 数组的定义、遍历和基本操作一次性讲清楚,帮你建立清晰的数组认知,为后续算法学习打基础。
📌 本文你将获得:
- 数组的基本概念和定义格式
- 静态初始化和动态初始化的区别与用法
- 数组元素的访问和修改方法
- 数组遍历的两种常用方式(for 循环和增强 for 循环)
- 数组的实战案例(求偶数和、最大值、数组反转等)
👋 关于作者
我是木圭,正在学习AI 智能应用开发,这是我从 0 开始系统学习 Java 的第 5 篇笔记。
我会持续记录从 0 基础到能独立开发 AI 应用的完整过程,包括学习笔记、项目实战、避坑指南。
关注我,一起见证从小白到开发者的成长之路!📅 学习进度:第 5 天 | JavaSE 基础阶段(共 17 篇,已完结 6 篇)
一、【核心概念/问题引入】
1.1 先搞懂核心:数组到底是什么?
把数组比作一个固定格子的柜子,一秒就懂了:
- 格子数量一开始定好就不能改(比如 5 个格子就永远 5 个)
- 格子里只能装同一种东西(全是整数 / 全是字符串 / 全是小数)
- 每个格子有编号(下标 / 索引),从 0 开始数(0、1、2、3…)
官方定义是:数组是用来存放「同一类型多个数据」的容器,它是连续排列的,有固定的长度。
1.2 为什么需要数组?
- 没有数组:处理多个同类型数据时需要创建无数个变量,代码臃肿,难以管理
- 有了数组:可以用一个变量存储多个同类型数据,通过索引访问,代码简洁,易于管理
二、【核心知识点详解】
2.1 数组的定义
是什么:数组是用来存放同一类型多个数据的容器。
怎么用:
- 样式 1:
数据类型 [] 数组名// eg:int [] arr - 样式 2:
数据类型 数组名 []// eg: int arr[] ———>C++用的较多
注意事项:
- 这种定义格式定义的只是数组类型的变量,还没有真正的创建出数组容器
- Java 语法中,第一种格式用的最多,第二种格式在 C 语言中比较常见
代码示例:
// 定义数组变量
int[] nums;
String[] names;
2.2 数组的初始化
是什么:初始化是在内存中,为数组容器开辟空间,并将数据存入容器中的过程。
怎么用:
- 静态初始化:
数据类型[] 数组名 = {值1, 值2, 值3...}; - 动态初始化:
数据类型[] 数组名 = new 数据类型[长度];
注意事项:
- 静态初始化:手动指定元素,系统计算出数组的长度
- 动态初始化:手动指定长度,系统会分配默认初始化值
代码示例:
// 静态初始化
int[] nums = {10, 20, 30, 40}; // 4个格子,值直接填好
String[] names = {"张三", "李四", "王五"};
// 动态初始化
int[] arr = new int[3]; // 定义一个长度为3的整数数组
2.3 数组的元素访问
是什么:通过索引访问和修改数组中的元素。
怎么用:数组名[索引];
注意事项:
- 索引从 0 开始,不能超过数组长度 - 1,否则会报错!
- 可以通过
数组名[索引] = 值来修改元素值
代码示例:
int[] arr = {11, 22, 33, 44};
// 打印元素33的值
System.out.println(arr[2]);
// 修改数组中44为88
arr[3] = 88;
System.out.println(arr[3]);
2.4 数组的遍历
是什么:遍历是把数组里的每一个值都取出来用一遍。
怎么用:
- 普通 for 循环:
for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } - 增强 for 循环:
for (int j : arr) { System.out.print(j + " "); }
注意事项:
- 普通 for 循环可以拿到索引,适合需要索引的场景
- 增强 for 循环代码更简洁,适合只读场景
代码示例:
int[] arr = {11, 33, 55, 77, 99};
// 普通for循环
System.out.println("普通for:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
// 增强for循环
System.out.println();
System.out.println("增强for:");
for (int j : arr) {
System.out.print(j + " ");
}
2.5 静态初始化与动态初始化的区别
| 对比维度 | 静态初始化 | 动态初始化 |
|---|---|---|
| 定义方式 | int[] arr = {11,22,33,44,55}; | int[] arr = new int[3]; |
| 长度确定 | 系统计算长度 | 手动指定长度 |
| 元素赋值 | 直接指定元素值 | 系统分配默认值 |
| 使用场景 | 明确要操作的数据 | 不明确要操作的数据 |
2.6 灵魂拷问:为什么数组索引从 0 开始?
"学到这你可能有疑问:为什么数组索引要从 0 开始,而不是从 1 开始?"
原因是:
- 计算机底层存储中,数组名存储的是第一个元素的内存地址
- 计算第 n 个元素的地址时,公式为:
首地址 + n * 元素大小 - 如果从 0 开始,计算更简单:
首地址 + 0 * 元素大小就是第一个元素的地址 - 这是计算机科学中的传统,大多数编程语言都采用这种方式
三、【实战案例】
3.1 案例 1:求偶数和与最大值(基础版)
需求描述:计算数组中所有偶数的和,并找出数组中的最大值。
代码实现:
public class ArrayDemo4 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66, 77, 88, 99};
// 1. 求偶数和
System.out.println("偶数和为:" + evenNumber(arr));
// 2. 求最大值
System.out.println("最大值为:"+getMax(arr));
}
/**
* 计算数组中所有偶数的和
*
* @param arr 整型数组
* @return 数组中所有偶数的和
*/
public static int evenNumber(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
sum += arr[i];
}
}
return sum;
}
/**
* 找出数组中的最大值
*
* @author Natural Pride
* @date 2026/3/20 19:53
* @param arr 整型数组
* @return 数组中的最大值
*/
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max=arr[i];
}
}
return max;
}
}
运行结果:
偶数和为:220
最大值为:99
3.2 案例 2:数组反转(进阶版)
需求描述:将数组中的元素值交换,实现数组反转。
代码实现:
public class ArrayReversalDemo {
public static void main(String[] args) {
int[] numbers = {11, 22, 33, 44, 55};
System.out.println("原始数组:");
printArray(numbers);
System.out.println();
int[] numbersCopy = numbers.clone();
System.out.println("========================");
System.out.println("使用方法 1 进行数组反转:");
System.out.println("反转前的数组:");
printArray(numbers);
System.out.println();
reverseByHalfLoop(numbers);
System.out.println();
System.out.println("========================");
System.out.println("使用方法 2 进行数组反转:");
System.out.println("反转前的数组:");
printArray(numbersCopy);
System.out.println();
reverseByTwoPointers(numbersCopy);
}
/**
* 反转数组元素顺序(方法 1)
* 使用普通 for 循环,只遍历数组长度的一半进行首尾元素交换
*
* @param arr 要反转的整型数组,原数组会被修改
*/
public static void reverseByHalfLoop(int[] arr) {
System.out.print("方法 1:");
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
System.out.println("反转后的数组:");
printArray(arr);
}
/**
* 反转数组元素顺序(方法 2)
* 使用双指针技术从数组两端向中心交换元素
*
* @param arr 要反转的整型数组,原数组会被修改
*/
public static void reverseByTwoPointers(int[] arr) {
System.out.print("方法 2:");
for (int left = 0, right = arr.length - 1; left < right; left++, right--) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
System.out.println("反转后的数组:");
printArray(arr);
}
public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
}
}
运行结果:
原始数组:
11 22 33 44 55
========================
使用方法 1 进行数组反转:
反转前的数组:
11 22 33 44 55
方法 1:反转后的数组:
55 44 33 22 11
========================
使用方法 2 进行数组反转:
反转前的数组:
11 22 33 44 55
方法 2:反转后的数组:
55 44 33 22 11
3.3 案例 3:评委打分(综合版)
需求描述:在编程竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分。选手的最后得分为:去掉一个最高分和一个最低分后的4个评委平均值。
代码实现:
public class ArrayCase {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr = new int[6];
System.out.println("请为选手打分:");
for (int i = 0; i < arr.length; i++) {
System.out.print("第" + (i + 1) + "位评委打分:");
arr[i] = sc.nextInt();
}
int average = getScore(arr);
System.out.println("该选手最后得分:" + average);
sc.close();
}
/**
* 计算数组元素去除一个最大值和一个最小值后的平均值
*
* @param arr 整数数组,至少包含2个元素
* @return 去除最大值和最小值后的平均值
*/
public static int getScore(int[] arr) {
int max = arr[0];
int min = arr[0];
int sum = 0;
// 单次遍历同时求最大值、最小值和总和
for (int i = 0; i < arr.length; i++) {
// 更新最大值
if (arr[i] > max) {
max = arr[i];
}
// 更新最小值
if (arr[i] < min) {
min = arr[i];
}
// 累加元素值
sum += arr[i];
}
// 去除最高和最低分后计算平均值
return (sum - max - min) / (arr.length - 2);
}
}
运行结果:
请为选手打分:
第1位评委打分:90
第2位评委打分:85
第3位评委打分:95
第4位评委打分:80
第5位评委打分:75
第6位评委打分:88
该选手最后得分:87
四、【避坑指南/常见问题】
⚠️ 坑点 1:数组索引越界
错误写法:
int[] arr = new int[3];
System.out.println(arr[3]); // 错误!索引最大为2
正确写法:
int[] arr = new int[3];
System.out.println(arr[2]); // 正确,索引范围是0-2
原因分析:数组索引从0开始,最大索引为数组长度-1,访问超出范围的索引会导致数组索引越界异常。
⚠️ 坑点 2:忘记数组长度是固定的
错误写法:
int[] arr = {1, 2, 3};
arr[3] = 4; // 错误!数组长度为3,索引最大为2
正确写法:
// 如果需要动态添加元素,应该使用 ArrayList
// int[] arr = {1, 2, 3}; // 长度固定为3
// 改为使用 ArrayList
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4); // 可以动态添加
原因分析:数组一旦创建,长度就固定不变,无法动态添加或删除元素。
⚠️ 坑点 3:混淆静态初始化和动态初始化
错误写法:
int[] arr = new int[3];
arr = {1, 2, 3}; // 错误!静态初始化只能在声明时使用
正确写法:
// 方式1:静态初始化
int[] arr = {1, 2, 3};
// 方式2:动态初始化后赋值
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
原因分析:静态初始化的简化语法只能在声明数组变量时使用,不能在后续赋值时使用。
五、【总结回顾】
📝 核心要点速记
- 数组是存放同一类型多个数据的容器,长度固定
- 数组索引从0开始,最大索引为数组长度-1
- 数组初始化分为静态初始化和动态初始化
- 遍历数组可以使用普通for循环或增强for循环
- 数组长度固定,无法动态添加或删除元素
🔥 面试高频题
- Q: 数组的特点是什么?
A: 数组是存放同一类型多个数据的容器,长度固定,元素连续存储,通过索引访问。 - Q: 静态初始化和动态初始化的区别是什么?
A: 静态初始化手动指定元素值,系统计算长度;动态初始化手动指定长度,系统分配默认值。 - Q: 数组索引为什么从0开始?
A: 因为数组名存储的是第一个元素的内存地址,从0开始计算地址更简单:首地址 + 0 * 元素大小。 - Q: 如何遍历数组?
A: 可以使用普通for循环(需要索引时)或增强for循环(只读场景)。
📚 系列文章导航
【JavaSE 从 0 到 1】系列(已完结 6/17 篇)
🔹 环境搭建篇
- ✅[第 1 篇] 还在卡 Java 环境?10 分钟搞定 JDK 配置的保姆级教程
- ✅ [第 2 篇] Java 开发必备:JDK 多版本共存与切换,一篇就够
🔹 语法基础篇
- ✅[第 3 篇] 你的 main 方法是不是写了 200 行?方法拆分技巧让代码清爽 10 倍
- ✅[第 4 篇] 告别语法混乱!Java 基础语法:理清变量、数据类型与运算符
🔹 流程控制篇
- ✅[第 5 篇] 告别逻辑混乱!Java 流程控制让代码学会"判断和循环"
🔹 数组篇
- ✅[第 6 篇] 数组入门必看!Java 数组定义、遍历 ← 当前这篇
🔹 面向对象篇
💬 互动区
- "你在学习数组的过程中遇到过什么问题?评论区聊聊~"
- "你觉得数组在实际开发中最常用的场景是什么?"
- "还想看哪些 Java 基础知识点的详解?留言告诉我!"
如果这篇文章对你有帮助,欢迎点赞 + 收藏,也欢迎转发给一起学习的小伙伴!
关注我,不错过后续的每一篇实战笔记!我们一起完成 AI 开发学习之旅~
📄 说明
- 作者:木圭
- 首发平台:掘金 / 微信公众号(搜索:木圭学编程)
- 转载请联系作者,注明出处
- 学习笔记仅供参考,欢迎指正错误