1. 数组与字符串:Java开发者的基本功修炼
作为Java开发者,数组和字符串是我们每天都要打交道的两种基础数据结构。很多人觉得它们简单,但真正能说清楚底层原理和高效使用技巧的开发者并不多。今天我们就来彻底剖析这两个看似简单实则暗藏玄机的数据结构。
我在实际开发中见过太多因为对数组和字符串理解不深导致的性能问题和内存泄漏。比如有一次排查线上OOM问题,发现就是因为开发者在循环里用"+"拼接字符串,生成了大量中间对象。还有一次发现数组越界导致的生产事故,只是因为开发者没搞清楚数组长度和集合size()的区别。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数组:固定长度的连续内存
2.1 数组的本质特性
数组是Java中最基础的数据结构之一,它的核心特点是:
- 固定长度:一旦创建,长度不可改变
- 连续内存:所有元素在内存中是连续存储的
- 同类型元素:只能存储相同类型的数据
- 快速访问:通过索引可以直接计算出内存地址,访问时间复杂度是O(1)
java复制// 数组声明和初始化的几种方式
int[] arr1 = new int[10]; // 动态初始化,所有元素默认为0
String[] arr2 = {"a", "b", "c"}; // 静态初始化
double[] arr3 = new double[]{1.1, 2.2, 3.3}; // 另一种静态初始化
注意:数组长度使用length属性获取,而String使用length()方法,集合使用size()方法。这个区别看似简单,但在实际开发中经常有人混淆。
2.2 数组的内存模型
理解数组的内存模型对性能优化很有帮助。数组在堆内存中分配一块连续的空间,每个元素的大小固定(如int是4字节)。当我们访问arr[i]时,JVM会根据数组首地址和索引i计算出元素的实际内存地址:
code复制元素地址 = 数组首地址 + i * 元素大小
这种计算方式使得数组的随机访问速度极快,这也是为什么很多高性能算法都基于数组实现。
2.3 多维数组的真相
Java中并没有真正的多维数组,所谓的多维数组实际上是"数组的数组"。比如二维数组就是一个一维数组,它的每个元素又是一个一维数组。
java复制// 不规则二维数组
int[][] matrix = {
{1, 2}, // 第一行2个元素
{3, 4, 5}, // 第二行3个元素
{6} // 第三行1个元素
};
// 遍历二维数组
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();
}
3. 字符串:不可变的艺术
3.1 为什么String是不可变的
String的不可变性是Java设计中一个非常精妙的特性。从JDK源码可以看到:
java复制public final class String {
private final
