Java中数组的使用
Java中数组的使用
介绍Java中数组的基本使用及需要注意的细节,对Java虚拟机的内存划分及数组在内存中的存储进行分析。
Author: Msuenb
Date: 2023-02-06
数组的概念
数组就是有限个相同数据类型的元素按照一定顺序排列的集合。数组中元素的编号称为下标/索引,数组中元素的个数称为数组的长度。
数组的特点:
- 数组长度一旦确定就不能修改。
- 创建数组时会在内存中开辟一整块连续的空间。
数组的分类
按照维度分
- 一维数组:存储一组数据
- 二维数组:存储多组数据,相当于一个二维表。二维数组每一行对应一个一维数组,不要求每一行的长度都一样。
按照存储元素类型分
- 基本数据类型元素:存储数据值
- 引用数据类型元素:存储对象引用(即该对象所在内存空间的首地址)
数组的声明与使用
主要是介绍一维数组的声明与使用,对于二维数组,可以看作多个一维数组的复合。其实,从数组底层的运行机制来看,并没有二维数组的存在。
一维数组的声明
-
一维数组的声明语法
Type[] name; // 推荐 Type name[]; // 不推荐
-
数组在声明时需要确定三部分内容:元素类型(int、String...)、维度([]、[][])、名称。
-
一维数组声明示例
int[] scores; System.out.println(scores); // 数组未初始化之前 不能使用 double prices[]; // 可以 不推荐 String[] names;
一维数组的初始化
初始化就是确定数组长度和元素的值。数组初始化有两种方式:静态初始化和动态初始化。
-
静态初始化
静态初始化就是用静态数据为数组初始化。此时数组长度由静态数据的个数决定。
-
一维数组静态初始化格式1:
Type[] name = {element1, element2, elenent3...}; // 必须在一个语句中完成 不能分开两个语句写
一维数组静态初始化实例1
int[] arr = {7, 4, 2, 6, 9}; // 正确 int[] arr; arr = {7, 4, 2, 6, 9}; // 错误
-
一维数组静态初始化格式2:
Type[] name = new Type[] {element1, element2, elelent3...}; // 可以分开 两个语句完成 或 Type[] name; name = new Type[] {element1, element2, elelent3...};
一维数组静态初始化示例2
int[] arr = new int[] {7, 4, 2, 6, 9}; // 正确 int[] arr; arr = new int[] {7, 4, 2, 6, 9}; // 正确
-
-
动态初始化
动态初始化就是先确定数组的长度,此时元素只是默认值,并不是真正的数据。真正的数据需要后续单独一个一个赋值。
-
一维数组动态初始化格式
Type[] name = new Type[length]; // length为数组的长度 即该数组能够存储数据的个数 或 Type[] name; name = new Type[length];
一维数组动态初始化示例
int[] arr = new int[5]; int[] arr; arr = new int[5]; int[] arr = new int[5] {1, 2, 3, 4, 5};//错误的,后面有{}指定元素列表,就不需要在[]中指定元素个数了。
-
关于动态初始化时元素的默认值
数据元素类型 元素默认初值 byte、short、int 0 long 0L float 0.0F double 0.0 char 0 或写为 '\u0000' boolean false 引用类型 null
-
一维数组的使用
-
如何获取数组长度(即数组中元素的个数)
Type[] name = {1, 2, 3, 4, 5} name.length; // 通过 数组名.length 获取数组的长度
-
如何表示数组中的一个元素?
name[index]; // 通过 数组名[下标/索引] 访问某个元素
Java中数组的下标范围:
[0 ~ name.length-1]
-
一维数组的使用演示
public class Main { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; System.out.println("arr数组的长度:" + arr.length); System.out.println("arr数组的第1个元素:" + arr[0]);//下标从0开始 System.out.println("arr数组的第2个元素:" + arr[1]); System.out.println("arr数组的第3个元素:" + arr[2]); System.out.println("arr数组的第4个元素:" + arr[3]); System.out.println("arr数组的第5个元素:" + arr[4]); System.out.println(arr[5]); // 运行出错 数组越界异常 //修改第1个元素的值 //此处arr[0]相当于一个int类型的变量 arr[0] = 100; System.out.println("arr数组的第1个元素:" + arr[0]); } }
二维数组的使用
-
静态初始化
int[][] arr = {{1,2,3},{4,5,6},{7,8,9,10}};//声明与初始化必须在一句完成 int[][] arr = new int[][] {{3,8,2}, {2,7}, {9,0,1,6}};
定义一个名称为
arr
的二维数组,arr
中有三个一维数组,且每个一维数组中的具体元素也都已初始化。第一个一维数组:
arr[0] = {3,8,2};
第一个一维数组:
arr[1] = {2,7};
第一个一维数组:
arr[2] = {9,0,1,6};
注意:
-
不要求二维数组中的每个一维数组长度一致
-
arr.length
不是二维数组中元素的个数,而是二维数组中一维数组的个数 -
arr[i].length
是二维数组中第i个一维数组的长度
-
-
动态初始化
int[][] arr = new int[3][2]; // 二维数组中有三个一维数组 每个一维数组中有两个元素 初始化值为0 int[][] arr = new int[3][]; // 每个一维数组初始化值为 null // 可以对这三个一维数组分别初始化 arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2]; int[][] arr = new int[][3]; // 错误
-
使用演示
public class Main { public static void main(String[] args) { int[][] arr = new int[][] {{3,8,2}, {2,7}, {9,0,1,6}}; System.out.println("arr数组的长度:" + arr.length); // 3 一维数组的个数 System.out.println("arr[1]的长度:" + arr[1].length); // 2 第二个一维数组的长度 System.out.println("arr[2]中的第3个元素:" + arr[2][2]); // 修改第一个一维数组中第二个元素的值 arr[0][1] = 100; System.out.println("arr[0]中的第二个元素:" + arr[0][1]); } }
-
注意特殊写法情况
int[] arr[]; // 正确 arr是一个二维数组 int[] x, arr[]; // 正确 x是一个一维数组 arr是一个二维数组 int arr[][]; // 正确
数组的内存分析
内存是用于暂存 CPU 中的运算数据,以及与硬盘等外部存储设备交换的数据。
JVM
的内存划分
Java 虚拟机要运行程序,必须对内存空间进行分配和管理。为了提高效率,就对空间进行了不同区域的划分,每一片区域都有特定的处理数据的方式和内存管理的方式。
区域名称 | 作用 |
---|---|
程序计数器 | 程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址 |
本地方法栈 | 当程序中调用了native的本地方法时,本地方法执行期间的内存区域 |
方法区 | 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 |
堆内存 | 存储对象(包括数组对象),new来创建的,都存储在堆内存。 |
虚拟机栈 | 用于存储正在执行的每个Java方法的局部变量表等。 局部变量表存放了编译期可知长度的各种基本数据类型、对象引用,方法执行完,自动释放。 |
一维数组在内存中的存储
public class Main {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);// [I@1b6d3586
System.out.println(arr[0]);// 0
}
}
上面程序执行流程
- 程序执行时,
JVM
会找到类中的main
方法,main
方法进入方法栈执行。 - 执行
int[] arr = new int[3];
创建数组时,JVM
会在堆内存中开辟出一片连续的空间,存储该数组。 JVM
将数组的首地址返回给引用变量arr
。
二维数据在内存中的存储
public class Main {
public static void main(String[] args) {
int[][] arr = new int[3][];
arr[1] = new int[2];
System.out.println(arr);// [[I@1b6d3586
System.out.println(arr[0]);// null
}
}