Java基础系列文章
Java基础(一):初识Java——发展历程、技术体系与JDK环境搭建
Java基础(二):八种基本数据类型详解
Java基础(三):逻辑运算符详解
Java基础(四):位运算符详解
Java基础(五):流程控制全解析——分支(if/switch)和循环(for/while)的深度指南
Java基础(六):数组全面解析
在 Java 中,数组(Array)是一种容器
,用于存储固定大小
的同一种数据类型
的多个元素。
数组在内存中是连续存储
的,每个元素通过索引(从 0 开始)来访问。
固定长度
:数组长度在创建时确定,不可动态改变
同类型元素
:所有元素必须是相同数据类型(基本类型或引用类型
)连续内存分配
:元素在内存中连续存储,支持高效随机访问索引访问
:通过索引(从0开始)访问元素,如arr[0]数组是对象
:继承自Object
类,可用Object类方法(如toString()),有length
属性,而不是方法默认值初始化
:创建时自动初始化默认值(如int为0,boolean为false,引用为null)按元素类型分类
类型 | 示例 | 特点 |
---|---|---|
基本类型数组 | int[] , char[] , double[] 等 |
存储基本数据类型值 |
对象引用数组 | String[] , Object[] , User[] 等 |
存储对象引用(内存地址) |
按维度分类
类型 | 声明方式 | 示例 | 特点 |
---|---|---|---|
一维数组(常用) | 数据类型[] 变量名 |
int[] arr = new int[3]; |
线性结构,单行元素 |
二维数组 | 数据类型[][] 变量名 |
int[][] matrix = new int[2][3]; |
表格结构(数组的数组) |
多维数组 | 数据类型[][][]... |
int[][][] cube = new int[3][3][3]; |
更高维度的数据(如三维空间) |
// 推荐声明方式(类型与[]结合)
int[] numbers;
// 合法但不推荐(C语言风格)
int numbers[];
可以替换 int 为任意基本数据类型(如 double, char, boolean)或引用类型(如 String, Student)
numbers = new int[5]; // 创建一个长度为 5 的整型数组,默认值为 0
int[] numbers = new int[5]; // 所有元素默认初始化为 0
// 标准格式
String[] names = new String[]{"Alice", "Bob", "Charlie"};
//或
String[] names;
names = new String[]{"Alice", "Bob", "Charlie"};
// 简写格式(自动推断长度)
int[] primes = {2, 3, 5, 7, 11};
int[] arr = new int[3]; // 分配5个int的内存(默认值: [0, 0, 0])
arr[0] = 10; // 通过索引赋值
错误写法:int[] arr = new int[5]{1,2,3,4,5}; //错误的,后面有{}指定元素列表,就不能在[]中指定元素个数了
栈
中创建引用变量 arr,初始值为 null(未指向任何对象)堆
中开辟连续内存空间元素类型
决定)首地址
被赋给栈中的引用变量 arr(如输出 arr 显示 [I@5f150435,[表示一维数组,I表示int类型,@后为地址的哈希值
)int[] arr = new int[3]; // 栈中arr保存堆地址0x001
arr[0] = 5; // 堆中0x001地址存入5
int[] arr2 = arr; // arr2复制arr的地址(指向同一堆对象)
arr2[1] = 9; // 修改影响arr[1](因共享堆内存)
首地址
是第一个元素的起始位置元素地址 = 首地址 + 下标 × 数据类型字节大小
首地址 + (下标-1)×字节大小
,多
出一次减法
运算i-1
计算,提升寻址效率 二维数组可以看成是数组的数组
,也可以理解为一个矩阵结构
。每个元素都是一个一维数组
。
int[][] matrix = new int[2][3]; // 两行三列,元素默认值为 0
这相当于:
[
[0, 0, 0],
[0, 0, 0]
]
// 标准版
int[][] matrix1 = new int[][]{
{1, 2, 3},
{4, 5, 6}
};
// 或者简写版
int[][] matrix = new int [][]{
{1, 2, 3},
{4, 5, 6}
};
int[][] jagged = new int[3][];
jagged[0] = new int[2]; // 第一行 2 个元素
jagged[1] = new int[4]; // 第二行 4 个元素
jagged[2] = new int[3]; // 第三行 3 个元素
注:int[][]arr = new int[][3]; //错误写法
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(); // 换行
}
for (int[] row : matrix) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
内层一维数组的引用
(指针)连续存储
的int[][] arr = new int[3][4]
会创建一个长度为 3
的数组(每个元素是 int[]
类型)独立分配
的连续内存块内存地址不连续
(可能分散在堆中)int[][] arr = new int[3][4];
内存结构示意图:
栈 (Stack)
┌──────┐
| arr │ → 指向堆中的外层数组
└──────┘
堆 (Heap)
外层数组 (连续) 内层数组 (独立连续块)
┌──────────┐ ┌───────────┐
│ arr[0] │ ─────→│ [0][0] = 0│
├──────────┤ │ [0][1] = 0│
│ arr[1] │ ──┐ │ [0][2] = 0│
├──────────┤ │ │ [0][3] = 0│
│ arr[2] │ ──┼──→└───────────┘
└──────────┘ │
│ ┌───────────┐
└──→│ [1][0] = 0│
│ [1][1] = 0│
│ [1][2] = 0│
│ [1][3] = 0│
└───────────┘
┌───────────┐
│ [2][0] = 0│
│ [2][1] = 0│
│ [2][2] = 0│
│ [2][3] = 0│
└───────────┘
toString()
:一维数组的可读字符串int[] arr = {1, 2, 3};
System.out.println(Arrays.toString(arr)); // 输出:[1, 2, 3]
deepToString()
:支持多维数组int[][] matrix = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(matrix)); // 输出:[[1, 2], [3, 4]]
asList()
:将数组转为固定大小
的List(不可增删,可修改元素
)String [] array = {"A","B","C"}
List<String> list = Arrays.asList(array);
list.set(0, "X"); // 允许修改
// list.add("D"); // 错误!UnsupportedOperationException
// 使用 ArrayList 构造函数,解决不能增删除的问题
List<String> list = new ArrayList<>(Arrays.asList(array));
int[] arr = {5, 2, 9, 1};
Arrays.sort(arr); // 结果:[1, 2, 5, 9]
Comparable
接口String[] names = {"John", "Alice", "Bob"};
Arrays.sort(names); // 结果:["Alice", "Bob", "John"]
Comparator
指定规则Arrays.sort(names, (a, b) -> b.compareTo(a)); // 逆序:["John", "Bob", "Alice"]
左闭右开
int[] arr = {5, 9, 1, 3};
Arrays.sort(arr, 1, 3); // 对索引 [1, 3) 区间排序,结果:[5, 1, 9, 3]
binarySearch()
:找到返回索引;未找到返回 -(插入点) - 1
,前提必须已排序
int[] sorted = {1, 3, 5, 7};
int index1 = Arrays.binarySearch(sorted, 5); // 返回 2(找到)
int index2 = Arrays.binarySearch(sorted, 4); // 返回 -3(未找到,插入点为 2)
equals()
:比较两个数组内容是否相等(长度和对应元素相同
)int[] a = {1, 2};
int[] b = {1, 2};
boolean isEqual = Arrays.equals(a, b); // true
deepEquals()
:用于多维数组
的深度比较int[][] matrix1 = {{1, 2}, {3, 4}};
int[][] matrix2 = {{1, 2}, {3, 4}};
boolean deepEqual = Arrays.deepEquals(matrix1, matrix2); // true
fill()
:将数组所有元素(或指定范围)设为指定值int[] arr = new int[3];
Arrays.fill(arr, 10); // [10, 10, 10]
Arrays.fill(arr, 1, 3, 5); // [10, 5, 5](索引 [1,3) 还是左闭右开)
copyOf()
:复制指定长度int[] original = {1, 2, 3};
int[] copy = Arrays.copyOf(original, 2); // [1, 2](截断)
int[] extended = Arrays.copyOf(original, 5); // [1, 2, 3, 0, 0](填充默认值)
copyOfRange()
:复制指定范围,还是左闭右开
int[] rangeCopy = Arrays.copyOfRange(original, 1, 3); // [2, 3](索引 [1,3))
parallelSort()
:利用多核处理器并行排序,适合大数据量(大于10000
时性能优势明显)int[] largeArray = ...;
Arrays.parallelSort(largeArray);
stream(T[] array)
:将数组转换为流(Stream
),可配合流式操作int[] arr = {1, 2, 3};
IntStream stream = Arrays.stream(arr);
stream.forEach(System.out::println);
// 数组转流并操作内部数据
long count = Arrays.stream(new int[]{1, 2, 3}).filter(x -> x > 1).count(); // 2
// 也可以实现数组转集合
int[] array = {1, 2, 3};
List<Integer> list = Arrays.stream(array) // IntStream
.boxed() // 装箱为 Integer
.collect(Collectors.toList());