Home Java数组和内存分配 - 数组使用
Post
Cancel

Java数组和内存分配 - 数组使用

关于数据内存管理一个重要知识点

关于数组变量数组对象两个概念。 数组变量只是一个引用变量(有点类似于C语言中的指针),而数组对象是保存堆内存空间的连续内存空间。 对于数组执行初始化,其实不是堆数组变量进行初始化,而是在堆内存中创建数组对象 - 就是为该数组对象分配一块连续的内存空间,这块连续的内存 空间就是数组的长度。比如有个数组

1
2
3
4
5
6
7
8
9
10
    public static void main(String[] args) {
      String[] a1 = new String[]{"篮球", "足球", "排球", "羽毛球"};

      //定义一个 String[] 类型的数组变量
      String[] a2 = null;
      System.out.println(a2);
      //将 a1 数组的引用赋值给 a2
      a2 = a1;
      System.out.println(a2.length);
    }

img.png

那如何区分引用变量和数组对象?

当引用变量不调用属性或方法,就是一个引用变量,当调用属性或方法时就会自动对应数组对象。

使用数组

数组的访问与修改

1
2
3
4
5
int[] arr = {10, 20, 30};
System.out.println(arr[0]); // 访问第一个元素,输出10
arr[1] = 200; // 修改第二个元素为200
System.out.println(arr.length); // 输出3(数组长度)
// System.out.println(arr[3]); // 报错:ArrayIndexOutOfBoundsException

数组的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int[] arr = {1,2,3};

// 1. 普通for循环(适合需要索引的场景)
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}

// 2. 增强for循环(简洁,无索引)
for (int num : arr) {
System.out.println(num);
}

// 3. Arrays.forEach(函数式风格)
Arrays.forEach(arr, num -> System.out.println(num));

数组的复制、扩容、排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int[] arr = {1,2,3};

// 1. 数组复制(System.arraycopy:手动指定源/目标、起始位置、长度)
int[] newArr1 = new int[5];
System.arraycopy(arr, 0, newArr1, 0, arr.length); // 把arr复制到newArr1的前3位
// newArr1 = [1,2,3,0,0]

// 2. 数组扩容(Arrays.copyOf:自动创建新数组,指定新长度)
int[] newArr2 = Arrays.copyOf(arr, 6); // 扩容到长度6,默认值补0
// newArr2 = [1,2,3,0,0,0]

// 3. 数组排序(Arrays.sort:原地排序,默认升序)
int[] unsortedArr = {3,1,2};
Arrays.sort(unsortedArr);
// unsortedArr = [1,2,3]

Java 没有 “真正的多维数组”,只有 “数组的数组”

很多人误以为 int[][] 是 “二维数组”,但 Java 本质上不存在连续内存的多维数组,所谓的 “多维数组” 只是「一维数组的嵌套」(数组的数组)—— 外层数组的每个元素是另一个数组的引用,而非直接存储多维数据。

1. 本质:“多维数组” 的内存布局

以 int[][] arr2d 为例,内存结构是两层嵌套:

  • 第一步:arr2d = new int[2][]; → 创建外层一维数组对象(长度 2),每个元素是 int[] 类型的引用(初始为 null); img_1.png
  • 第二步:arr2d[0] = new int[3]; arr2d[1] = new int[4]; → 为外层数组的每个引用指向内层一维数组对象(长度可不同) img_2.png

2. 两种 “多维数组” 创建方式(规则 vs 不规则)

(1)规则 “二维数组”(伪多维)

看似是二维数组,实则是外层数组的每个元素指向长度相同的内层数组:

1
2
3
4
// 简化写法:创建2行3列的“二维数组”(外层长度2,内层每个长度3)
int[][] arr2d = new int[2][3];
arr2d[0][1] = 10; // 外层第0个引用 → 内层数组第1个元素赋值
System.out.println(arr2d[0][1]); // 输出10

(2)锯齿数组(不规则数组,体现 “数组的数组” 本质)

1
2
3
4
5
6
7
8
9
// 第一步:创建外层数组(长度3,元素为int[]引用,初始null)
int[][] jaggedArr = new int[3][];
// 第二步:为每个外层元素指向不同长度的内层数组
jaggedArr[0] = new int[2];  // 第0行:2列
jaggedArr[1] = new int[5];  // 第1行:5列
jaggedArr[2] = new int[1];  // 第2行:1列

jaggedArr[1][3] = 20; // 第1行第3列赋值20
System.out.println(jaggedArr[1][3]); // 输出20

weixin.png

公众号名称:怪味Coding
微信扫码关注或搜索公众号名称
This post is licensed under CC BY 4.0 by the author.