数组
学习目标:
- 理解容器的概念
- 掌握数组的定义方式
- 使用索引访问数组
- 了解数组的内存图解
- 空指针和越界异常
- 数组的遍历
- 数组最大值的获取
- 数组元素的统计
- 数组的复制和反转
学习内容:
第四章、数组
4-1、容器的概念
- 将多个数据存储到一起,每个数据成为该容器的元素
- 生活中的容器:水杯,教师等
4-2、数组的概念
- 用于存储数据长度固定的容器,保证多个数据的类型要一致
数组的特点:
1、数组的长度一旦确定不能修改
2、创建数组时会在内存中开辟一整块连续的空间
3、存取元素快,可以通过下标定位元素
4-3、数组的定义
1、静态初始化
数据类型[] 数组名 = {元素1,元素2,……};
int[] arr = {1,2,4,5,6};
2、静态初始化
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
或
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3...};
int[] arr = new int[]{1,2,3,4,5};//正确
int[] arr;
arr = new int[]{1,2,3,4,5};//正确
3、动态初始化
数组存储的元素的数据类型[] 数组名字 = new 数组存储的元素的数据类型[长度];
或
数组存储的数据类型[] 数组名字;
数组名字 = new 数组存储的数据类型[长度];
定义可存储5个整数的数组:
int[] arr = new int[5];
int[] arr;
arr = new int[5];
4-4、数组元素的访问
数组名[索引]
-
索引访问数组中的元素:
- 数组名[索引]=数值,为数组的元素赋值
- 变量=数组名[索引],获取数组中的元素
public class ArrayDemo1 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
arr[0] = 6;
int i = arr[0];
System.out.println(i);
System.out.println(arr[0]);
}
}
4-5、数组的遍历
- 获取数组的长度 :数组名.length
- 数组的遍历
public class ArrayFor {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
System.out.println("数组的长度"+arr.length);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
4-6、数组元素的默认值
数组存储的元素的数据类型[] 数组名字 = new 数组存储的元素的数据类型[长度];
数组元素默认值
数组元素类型 | 元素的默认初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0或\u0000(空) |
boolean | false |
引用类型 | null |
4-7、数组使用中遇见的异常
1、数组越界异常
public class ArrDemo {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[3]);
}
}
数组异常:Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 3
at ArrDemo.main(ArrDemo.java:4)
原因:数组越界
解决办法:数组定义错了,修改正确定义
2、数组空指针异常
public class ArrDemo2{
public static void main(String[] args) {
int[] arr = {1,2,3};
arr = null;
System.out.println(arr[0]);
}
}
原因分析:
arr = null
这行代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出NullPointerException
空指针异常
空指针异常在内存图中的表现
4-8、数组的内存图
内存:
内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。
1、Java虚拟机的内存划分
名称 | 解释 |
---|---|
程序计数器 | 程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址 |
本地方法栈 | 当程序中调用了native的本地方法时,本地方法执行 |
方法区 | 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 |
堆内存 | 存储对象(包括数组对象),new来创建的,都存储在堆内存 |
虚拟机栈 | 用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度的各种基本数据类型、对象引用,方法执行完,自动释放。 |
2、数组在内存中的存储
① 一个数组的内存图
public class ArrDemo3 {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);
}
}
注意:
- arr中存储的是数组的首地址,但是因为数组是引用数据类型,打印arr时,会自动调用arr数组对象的toString()方法,默认该方法实现的是对象类型名@该对象的hashCode()值的十六进制值
- 数组下标从0开始的原因是:第一个元素距离数组首地址间隔0个单元
②两个数组内存
public class ArrDemo4 {
public static void main(String[] args) {
int[] arr = new int[3];
int[] arr2 = new int[2];
System.out.println(arr);
System.out.println(arr2);
}
}
③两个变量指向一个数组
public class ArrDemo5 {
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]);
}
}
4-9、数组常见操作
1、数组的最值
public class Arr_MaxDemo {
public static void main(String[] args){
int[] arr = {4, 5, 6, 1, 2, 8, 9};
int max = arr[0];
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
} else if (arr[i] < min) {
min = arr[i];
}
}
System.out.println(max);
System.out.println(min);
}
}
2、数组中找最值及其下标
public static void main(String[] args){
int[] arr = {4, 5, 6, 1, 2, 8, 9};
int index = 0;
int index1 = 0;
int max = arr[0];
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
index = i;
} else if (arr[i] < min) {
min = arr[i];
index1 = i;
}
}
System.out.println(max+"下标:"+index);
System.out.println(min+"下标:"+index1);
}
3、求数组总和,均值、总乘积、偶数个数
public class Arr_Statistics {
public static void main(String[] args) {
int[] arr={4,5,6,9,2};
//求总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//求均值
double avg = (double) sum / arr.length;
//求总乘积
long result = 1;
for (int i = 0; i < arr.length; i++) {
result *= arr[i];
}
//统计偶数个数
int even = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
even++;
}
}
System.out.println("总和:"+sum);
System.out.println("均值:"+avg);
System.out.println("总乘积:"+result);
System.out.println("偶数个数:"+even);
}
}
4、扩容
新增一个位置存储6
public class Arr_Dilatancy {
public static void main(String[] args){
int[] arr = {1, 2, 3, 4, 5};
int[] newarr = new int[arr.length+1];
//复制元素
for (int i = 0; i < arr.length; i++) {
newarr[i] = arr[i];
}
//把新元素添加到最后
newarr[newarr.length - 1] = 6;
//如果下面继续使用arr,可以让arr指向新数组
arr = newarr;
//遍历显示
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
5、备份
public class Arr_Cp {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int[] newArr = new int[arr.length];
//复制元素
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
//遍历显示
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
6、截取[start,end]范围
public class Arr_Intercept {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int start = 1;
int end = 3;
//创建一个新数组长度=end-start;
int[] newArr = new int[end - start];
//赋值元素
for (int i = 0; i < newArr.length; i++) {
newArr[i] = arr[start + i];
}
//遍历显示
for (int i = 0; i < newArr.length; i++) {
System.out.println(newArr[i]);
}
}
}
7、反转
方法:
① 借助一个新数组
②收尾对应位置交换
//方法一
public class Arr_Rollback {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//创建一个新数组
int[] newArr = new int[arr.length];
//赋值元素
int len = arr.length;
for (int i = 0; i < newArr.length; i++) {
newArr[i] = arr[len - 1 - i];
}
//舍弃旧址,让arr指向新数组
arr = newArr;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
方法二:
实现:数组对称位置的元素互换
public class Arr_Rollback2 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
//(1)计算要交换的次数: 次数 = arr.length/2
//(2)首尾对称位置交换
for(int i=0; i<arr.length/2; i++){//循环的次数就是交换的次数
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
//(3)遍历显示
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
}
}
- 实现反转,就需要将数组对称位置的元素进行交换
- 定义两个变量,保存数组的最小索引和最大索引
- 两个索引上的元素交换位置
- 最小索引++,最大索引–
- 最小索引超过了最大索引,数组反转操作结束
public class Arr_Rollback3 {
public static void main(String[] args){
int[] arr = {1,2,3,4,5};
//首尾交换
for(int min=0,max=arr.length-1; min<max; min++,max--){
//首 与 尾交换
int temp = arr[min];
arr[min] = arr[max];
arr[max] = temp;
}
//(3)遍历显示
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
}
}
学习时间:
- 周一至周天晚上 7 点—晚上9点