数组
一、数组概述
-
数组的概念:
- 数组(array),就是多个相同类型的数据按一定顺序排列的集合,并使用一个名字命名,然后用编号区分这些数据。
- 数组就是一个数据容器。
-
相关概念:
- 数组名
- 下标(或脚标、索引)(index)
- 元素(element)
- 数组的长度(length)
-
数组的特点:
- 数组的长度一旦确定就不能修改(重要)
- 存储的元素为相同的数据类型,可以是基本数据类型或引用数据类型
- 有索引,创建数组时会在内存中开辟一整块连续的空间。
- 存取元素的速度快,因为可以通过[下标],直接定位到任意一个元素。
二、数组的声明与初始化
数组在使用之前需要先进行声明并初始化
-
数组的声明
//推荐
元素的数据类型[] 数组的名称;
int[] age;
//不推荐
元素的数据类型 数组名[];
int age[]; -
数组的初始化
数组使用之前需要先初始化,什么是数组初始化?就是给数组分配内存空间,并给元素赋值。
数组有两种初始化方式:
方式一:静态初始化
定义数组的同时为数组分配内存空间,并赋值。程序员只给定数组元素的初始值,不指定数组长度,由系统决定数组的长度
格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3…};
或
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3…};
简化方式:
数据类型[] 数组名 = {元素1,元素2,元素3…};//必须在一个语句中完成,不能分开两个语句写
举例:
int[] arr = new int[]{1,2,3,4,5};//正确
int[] arr;
arr = new int[]{1,2,3,4,5};//正确
int[] arr = new int[5]{1,2,3,4,5};//错误的,后面有{}指定元素列表,就不需要在[长度]指定长度。
//简化方式:
int[] arr = {1,2,3,4,5};//正确
int[] arr;
arr = {1,2,3,4,5};//错误
方式二:动态初始化
程序员只给定数组的长度,后期再给给元素赋值(实际系统会先给出元素的默认值)
格式:
数据类型[] 数组名字 = new 数据类型[长度];
或
数据类型[] 数组名字;
数组名字 = new 数据类型[长度];
格式详解:
- 数据类型: 指定创建的数组容器可以存储什么数据类型的数据。
- [] : 表示数组。
- 数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。
- new:关键字,理解为开辟内存空间。因为数组本身是引用数据类型,所以要用new创建数组对象。
- [长度]:数组的长度,表示数组容器中可以存储多少个元素。
- 注意:数组有定长特性,长度一旦指定,不可更改。
- 和水杯道理相同,买了一个2升的水杯,总容量就是2升,不能多也不能少。
三、 数组元素的访问
-
索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
-
索引范围:[0, 数组的长度-1]
-
格式:
数组名[索引]
访问数组元素:
-
数组名[索引],表示指定索引位置的元素
-
数组名[索引]=值,表示为数组中指定索引位置的元素赋值
四、数组的遍历
- 数组遍历:将数组中的每个元素分别获取出来
- 数组的长度属性:
数组名.length
,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1
。
//数组遍历(正序):
System.out.println("数组遍历:");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//数组遍历(逆序):
System.out.println("数组逆序遍历:");
for (int i = arr.length-1; i >=0 ; i--) {
System.out.println(arr[i]);
}
五、 数组元素的默认值
当我们使用动态初始化创建数组时:
数据类型[] 数组名字 = new 数据类型[长度];
此时只确定了数组的长度,那么数组的元素是什么值呢?
数组的元素有默认值:
六、数组内存图分析
思考:打印arr为什么是[I@5f150435,它是数组的地址吗?
答:它不是数组的地址。
问?不是说arr中存储的是数组对象的首地址吗?
答:arr中存储的是数组的首地址,但是因为数组是引用数据类型,打印arr时,会自动调用arr数组对象的toString()方法,默认该方法实现的是对象类型名@该对象的hashCode()值的十六进制值。
问?对象的hashCode值是否就是对象内存地址?
答:不一定,因为这个和不同品牌的JVM产品的具体实现有关。例如:Oracle的OpenJDK中给出了5种实现,其中有一种是直接返回对象的内存地址,但是OpenJDK默认没有选择这种方式。
两个变量指向一个数组
public static void main(String[] args) {
// 定义数组,存储3个元素
int[] arr = new int[3];
//数组索引进行赋值
arr[0] = 5;
arr[1] = 6;
arr[2] = 7;
//输出3个索引上的元素值
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
//定义数组变量arr2,将arr的地址赋值给arr2
int[] arr2 = arr;
arr2[1] = 9;
System.out.println(arr[1]);
}