5.1 容器概念
情景分析:现在需要统计一个班级里面的身高状况,比如平均身高,最高身高等,假如该班级有50个人,用之前变量的知识,那么就需要创建50个变量来记住每个人的身高,然后再对这50个变量进行操作,这样就会很麻烦,而且错误率也高。因此我们可以用容器来操作,将所有数据存入一个容器中,统一操作。
- 容器:是将多个数据存储在一起,每个数据称为容器的一个元素。
- 生活中的容器:水杯,书架,教室等等。
5.2 数组
5.2.1 概念
数组就是存储数据长度固定的容器,保证容器中的各个数据的数据类型要一致。
5.2.2 定义
数组存储的数据类型[] 数组名;
5.2.3 初始化
格式一
数据类型[] 数组名 = new 数据类型[长度];
int num = new int[5];
格式二
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3....};
int[] num = new int[]{1,2,4,33,78};
格式三
数据类型[] 数组名 = {元素1,元素2,元素3.....};
int num = {1,3,4,33,78};
注意:数组有定长特性,长度一旦指定,便不可更改。
5.2.4 数组访问
索引:每一个存储到数组中的元素,都会自动拥有一个编号,从0开始,这个编号就是数组索引(index),可以通过数组的索引访问到数组中的元素。
格式:数组名[索引]
长度属性:每个数组都有长度,且是不可变的,java数组中有length这个属性来获取到数组的长度,语句为数组名.length,结果为int类型,由于数组下标(索引)是从0开始的,所以数组索引的最大值为数组名.length-1。
访问数组元素:
1.数组名[索引] = 数组; 为数组中的元素赋值
2.变量 = 数组名[索引]; 获取数组中的元素
public static void main(String[] args) {
//定义数组并初始化
int[] num = new int[]{1,2,4,33,78};
//给数组元素赋值
num[0]=6;
//获取数组元素
int i = num[0];
System.out.println("i="+i);//打印结果为6
//获取数组长度
int len = num.length;
System.out.println("数组的长度为"+len);//打印结果为5
}
5.3 数组内存原理
5.3.1 内存概述
内存是计算机中的一个重要元件,是临时存储区域,用于运行程序。我们编写的程序是放在硬盘里的,在硬盘中是不会运行的,必须要将程序放在内存中才能运行,运行完毕会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间分配和管理。
5.3.2 Java虚拟机的内存划分
为了提高运行效率,JVM就对内存空间进行了不同区域的划分,每一片区域都有特定的数据处理方式和内存管理方式。
- JVM内存划分
区域名称 | 作用 |
---|---|
寄存器 | 给CPU使用的,与我们开发无关 |
本地方法栈 | JVM在使用操作系统功能时使用,与我们开发无关 |
方法区 | 存储可以运行的class文件 |
堆内存 | 存储对象或数组,new创建的,都存储在堆内存 |
方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行 |
5.3.3 数组在内存中的存储
public static void main(String[] args) {
int[] arr = new int[2];
int[] arr2 = new int[3];
System.out.println(arr);//[I@129a8472
System.out.println(arr2);//[I@1b0375b3
}
上面的执行结果为[I@129a8472和[I@1b0375b3,这两个结果就是数组在内存的地址,new出来的内容都是放在堆内存中的,而方法中变量arr保存的就是数组的地址。
比如输出arr[0],就是输出arr保存的地址中索引为0的元素。
可以理解为arr表示的是一间酒店的地址,而索引就是门牌号,找某一间房间就需要先找到该酒店,再找该酒店中的那间房间。
程序执行流程:
1.main方法进入方法栈中执行
2.创建数组,JVM会在堆内存中开辟空间,存储数组
3.数组在内存中会有自己的内存地址,以十六进制表示
4.arr中有2个元素,默认值为0
5.JVM将数组的内存地址赋值给引用类型变量arr
6.变量arr保存的是数组在内存中的地址,而不是一个具体数值,所以叫引用数据类型。
- 两个变量指向一个数组
public static void main(String[] args) {
int[] arr = new int[3];
arr[0]=88;
arr[1]=33;
arr[2]=66;
int[] arr2 = new int[3];
arr2[0]=22;
arr2[1]=44;
arr2[2]=55;
int[] arr3 = arr;
arr3[0]=100;
arr3[1]=200;
System.out.println(arr[0]);//100
System.out.println(arr[1]);//200
System.out.println(arr[2]);//66
}
5.3.4 数组操作常见异常
- 数组越界:数组长度是固定的,一旦操作超过数组长度的元素时,就会报数组越界异常。
public static void main(String[] args) {
int[] arr = {1,2,3};
//索引最大值为length-1=2
System.out.println(arr[3]);
}
- 空指针异常
public static void main(String[] args) {
int[] arr = {1,2,3};
//这时候arr便不再指向数组在内存中的地址了
arr=null;
System.out.println(arr[0]);
}
这两种异常都是不能忽略的,一旦出现,必须修改代码。
练习:遍历数组中的元素
public static void main(String[] args) {
int[] arr = new int[]{1,3,5,7,9};
//不使用循环来遍历
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
System.out.println("------------");
//使用for循环来遍历
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
遍历数组是将数组中所有元素获取出来,遍历是数组操作中最基本的操作。
5.4 方法的参数传递
概念
- 当我们在调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用这些值去进行运算,这种传递方式称为参数传递。参数列表中的变量称为形式参数,简称形参。调用方法时,传入方法中的值称为实际参数,简称实参。
- 形式参数的改变不会影响实际参数的值。
public static void main(String[] args) {
int a=10;
System.out.println("a="+a);//a=10
int a1 = changeNumber(a);
System.out.println("a1="+a1);//a1=100
System.out.println("a="+a);//a=10
}
public static int changeNumber(int a){
a=a*10;
return a;
}