多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 【数组】 ##### 今日复习指南 ~~~ 1.简化格式初始化数组的使用(0.5个小时内完成,多写几遍) Demo01UseArray.java         2.数组的遍历(0.5个小时内完成,多写几遍)    Demo01ArrayEach.java     3.数组的最大值(1个小时,多写几遍)    Demo03ArrayMax.java ~~~ ##### 今日内容 ~~~ 数组的概念和数组变量的定义【重点】 数组的初始化及使用【重点的重点】 ---------------最核心的内容-------------- 数组的内存图【理解】 数组的常见问题【理解】 数组的练习【重点的重点】   ---------------最核心的内容--------------     快捷键:    生产输出语句: 表达式.sout    数组遍历:   数组名.fori: 正着遍历   数组名.forr: 倒着遍历 ~~~ ### 第一章 数组定义和访问【理解】 ##### 1.1 容器的概念 ~~~ 一个变量中只能存储存储一个数据,新的数据进来,老的数据被替换,如果要存储多个数据,需要使用容器 ​ 容器:是将多个数据存储到一起,每个数据称为该容器的元素。 生活中的容器:水杯,衣柜,鞋柜, 教室 ​ 数组: 1.概念: java中的数组就是一个容器,可以存储多个数据,但是这多个数据的类型必须保持一致    2.特点:   (1)可以存储多个数据   (2)多个数据的类型必须保持一致   (3)数组长度一旦创建,永远不可以发生改变       public class Demo01Box { //-----------------------此代码不用敲--------------------------------    public static void main(String[] args) {                //比如我们班有80个学生需要参加考试,每个学生对应一个成绩(整数)        //可以定义80个int变量        int a = 80;        int b = 90;        int c = 70;        int d = 50;        int e = 85;        int f = 95;        int g = 59;        int h = 63; ​        //需要求总分        int sum = a + b + c + d + e + f + g + h; ​        //需要求平均分        int avg = sum/80; ​        //需要求最高分和最低分: 实现起来非常麻烦 ​ ​   } }           ~~~ ##### 1.2 数组变量的定义 ~~~ 数组变量: 专门用来存储数组容器的变量 ​ 1.数组变量定义格式一: 推荐使用的格式 数据类型[] 数组名称1; ​ 2.数组变量定义格式二: 不推荐使用的格式 数据类型 数组名称[]; 1.定义一个存储int类型数组的变量arrayA 2.定义一个存储double类型数组的变量arrayB 3.定义一个存储char类型数组的变量arrayC int[] arrayA: 这里只是定义了一个用来存储数组容器的变量,相当于门牌 但是对应的教室现在/目前还没有        目前还没有创建出真正的数组容器 ~~~ ~~~ public class Demo02Array {    public static void main(String[] args) { ​        //定义int变量num,未赋值        int num;        //System.out.println(num);//错误: 变量中没有数据,不能使用 ​        //1.定义一个存储int类型数组的变量arrayA        //int类型数组: 该容器只能存储int类型的数据        int[] arrayA; ​        //错误: 目前只是定义好了一个用来存储数组容器的变量,但是还没有向该变量中存储数组呢        //System.out.println(arrayA); ​        //2.定义一个存储double类型数组的变量arrayB        //double类型数组: 该容器只能存储double类型的数据        double arrayB[]; ​        //3.定义一个存储char类型数组的变量arrayC        //char类型数组: 该容器只能存储char类型的数据        char[] arrayC; ​ ​   } } ​ ~~~ ##### 图解: ![](https://img.kancloud.cn/56/3e/563e393f73fba600ebf7b576884b59ae_1302x508.png) ##### 1.3 数组的第一种初始化方式 ~~~ 数组的第一种初始化方式(动态初始化,指定数组的长度) 1.格式:   数据类型[] 数组名称 = new 数据类型[长度]; ​    2.格式解释:   (1)左侧数据类型: 表示数组容器中可以存储什么类型的数据   (2)左侧[]: 表示数组的意思   (3)数组名称: 就是给数组起个名字,方便找到对应的数组   (4)=: 把右侧的数组容器存储到左侧的数组变量中   =就是赋值,只是给数组变量赋的是数组容器在内存中的地址值   (5)new: 在内存中创建数组容器的过程   (6)右侧数据类型: 和左侧保持一致       (7)长度: 数组中可以存储多少个数据 ​ 3.练习: (1)创建一个int类型的数组,可以存储3个int数据,给该数组起个名称叫做arrayA   (2)创建一个double类型的数组,可以存储7个double数据,给该数组起个名称叫做arrayB   (3)创建一个char类型的数组,可以存储5个char数据,给该数组起个名称叫做arrayC       ​ ~~~ ~~~ public class Demo03Array {    public static void main(String[] args) {        //(1)创建一个int类型的数组,可以存储3个int数据,给该数组起个名称叫做arrayA        int[] arrayA = new int[3]; ​        //(2)创建一个double类型的数组,可以存储7个double数据,给该数组起个名称叫做arrayB        double[] arrayB = new double[7]; ​        //(3)创建一个char类型的数组,可以存储5个char数据,给该数组起个名称叫做arrayC        char[] arrayC = new char[5]; ​ ​   } } ​ ~~~ ##### 1.4 数组的第二种初始化方式 ~~~ 数组的第二种初始化方式(标准格式静态初始化: 指定数组元素) 1.格式:   数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,元素3...};    2.注意:   (1){}中的多个元素之间用逗号隔开,最后一个元素后面没有逗号 (2)右侧[]中不用写长度,JVM会根据{}中的元素数量,推导出长度    3.练习:   (1)创建一个int类型的数组,可以存储多个int数据100,200,300,给该数组起个名称叫做arrayA       (2)创建一个double类型的数组,可以存储多个double数据1.1,2.2,3.3,4.4,5.5,6.6,7.7,给该数组起个名称叫做arrayB       (3)创建一个char类型的数组,可以存储多个char数据'真','的','好','想','你',给该数组起个名称叫做arrayC             ~~~ ~~~ public class Demo04Array { public static void main(String[] args) { //(1)创建一个int类型的数组,可以存储多个int数据100,200,300,给该数组起个名称叫做arrayA int[] arrayA = new int[]{100,200,300}; //(2)创建一个double类型的数组,可以存储多个double数据1.1,2.2,3.3,4.4,5.5,6.6,7.7,给该数组起个名称叫做arrayB double[] arrayB = new double[]{1.1,2.2,3.3,4.4,5.5,6.6,7.7}; //(3)创建一个char类型的数组,可以存储多个char数据'真','的','好','想','你',给该数组起个名称叫做arrayC char[] arrayC = new char[]{'真','的','好','想','你'}; } } ~~~ ##### 1.5 数组的第三种初始化方式 ~~~ 数组的第三种初始化方式(简化格式的静态初始化: 指定元素) 1.格式: 数据类型[] 数组名称 = {元素1,元素2,元素3...}; 2.练习: (1)创建一个int类型的数组,可以存储多个int数据100,200,300,给该数组起个名称叫做arrayA (2)创建一个double类型的数组,可以存储多个double数据1.1,2.2,3.3,4.4,5.5,6.6,7.7,给该数组起个名称叫做arrayB (3)创建一个char类型的数组,可以存储多个char数据'真','的','好','想','你',给该数组起个名称叫做arrayC 3.注意: (1){}中的多个元素之间用逗号隔开,最后一个元素后面没有逗号 (2)不需要指定长度,JVM根据{}中元素的数量推导数组长度 (3)虽然没有写new,但是底层/内部仍然有new的过程 (4)对于动态初始化和标准格式的静态初始化数组,可以分成两步完成 (5)对于简化格式静态初始化方式,不可以分成两步完成 java中的规定 ~~~ ~~~ public class Demo05Array { public static void main(String[] args) { //(1)创建一个int类型的数组,可以存储多个int数据100,200,300,给该数组起个名称叫做arrayA int[] arrayA = {100, 200, 300}; //(2)创建一个double类型的数组,可以存储多个double数据1.1,2.2,3.3,4.4,5.5,6.6,7.7,给该数组起个名称叫做arrayB double[] arrayB = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7}; //(3)创建一个char类型的数组,可以存储多个char数据'真','的','好','想','你',给该数组起个名称叫做arrayC char[] arrayC = {'真', '的', '好', '想', '你'}; int a; a = 10; System.out.println(a); a = 20; System.out.println(a); int[] array;//定义存储一个int类型数组的变量array array = new int[3];//把长度为3的int数组,存储到变量array中 array = new int[]{10,20,30,50};//把存储多个int数据的int数组,重新存储到变量array中 int[] arr /*= {100,200,300,500}*/; //arr = {100,200,300,500};//错误: java中规定,简化格式静态初始化数据进行赋值时,不能分成两步完成 } } ~~~ ##### 1.6 数组的使用 ~~~ /* 数组的使用 ============================================重点重点重点========================================= 1.数组名称: 代表数组在内存中的地址值,是一个16进制的整数数字 2.索引编号: 是一个整数数字 (1)数组中的每个数据,称之为数组元素 (2)数组为内部的每个元素进行了一个数字编号(整数数字),称为索引/角标 索引从0开始到最大值(数组长度 减 1) 3.数组元素: 数组名称[索引编号] 比如: array[2]: 数组array中索引编号为2的元素 4.数组长度的获取: 每个数组内部都有一个length属性,保存数组用元素的个数 数组名称.length: 是一个int数字,代表数组的长度 注意: length后面是没有()的 */ public class Demo01UseArray { public static void main(String[] args) { //int num = 10; //System.out.println(num);//10 //创建int类型数组array,并初始化 int[] array = new int[]{100,200,300};//100的索引编号是0,200的索引编号是1,300的索引编号是2 //数组名称: 代表数组在内存中的地址值,是一个16进制的整数数字 System.out.println(array);//[I@1540e19d //打印100 System.out.println(array[0]);//打印数组array中索引编号为0的元素的值: 100 //打印200 System.out.println(array[1]);//打印数组array中索引编号为1的元素的值: 200 //打印300 System.out.println(array[2]);//打印数组array中索引编号为2的元素的值: 300 System.out.println("---------------"); //把100修改为1000 array[0] = 1000;//把数字1000存储到array中索引编号为0的元素中 //把200修改为2000 array[1] = 2000;//把数字2000存储到array中索引编号为1的元素中 //把300修改为3000 array[2] = 3000;//把数字3000存储到array中索引编号为1的元素中 //打印1000 System.out.println(array[0]);//打印数组array中索引编号为0的元素的值: 1000 //打印2000 System.out.println(array[1]);//打印数组array中索引编号为1的元素的值: 2000 //打印3000 System.out.println(array[2]);//打印数组array中索引编号为2的元素的值: 3000 System.out.println("---------------"); //获取数组array的长度,是一个int数字,保存到int变量count中 int count = array.length; System.out.println("数组长度: "+count); System.out.println("数组长度: "+array.length); System.out.println("---------------"); /* array.length的值: 3 打印数组元素,数组元素的所有格式: 数组名[索引编号] array[array.length-1]: 先计算array.length-1 ==> 3 - 1 ==> 2 上面的式子等价于array[2]: 3000 */ System.out.println(array[array.length-1]);//3000 } } ~~~ ### 第二章 数组原理内存图【理解】 ##### 2.1 java中的内存分配 ~~~ 1.方法区: 存储可以运行的class文件。 2.方法栈: 方法运行时使用的内存,比如main方法运行,进入方法栈中执行。 3.堆内存 存储对象或者数组,new来创建的,都存储在堆内存。 4.寄存器 给CPU使用,和我们开发无关 不关心 5.本地方法栈 JVM在使用操作系统功能的时候使用,和我们开发无关。 不关心 今天主要使用: 1.栈内存: 运行方法的,存储方法中定义的变量的 2.堆内存: 存储的是所有new出来的内容 ~~~ ##### 图解: ![](https://img.kancloud.cn/ae/af/aeaf9e2e29cd005685aedafaa4fafa78_1261x525.png) ##### 2.2 一个数组内存图 ~~~ /* 一个数组的内存图解 1.数组名称: 数组在堆内存空间的地址值,16进制的整数数字 2.数组元素有默认值 (1)整数数组 0 (2)小数数组 0.0 (3)字符数组 空白字符 (4)布尔数组 false (5)引用类型: null 3.注意: (1)数组变量保存数组在堆内存中的地址值,通过地址值找到对应的数组 (2)数组元素都有索引编号,通过索引编号找到对应的元素 */ public class Demo01OneArray { public static void main(String[] args) { //创建int类型数组one,长度为2 int[] one = new int[2]; System.out.println(one);//数组名称: 数组在堆内存空间的地址值,16进制的整数数字: [I@1540e19d System.out.println(one[0]);//打印数组one中索引编号0对应的元素的值,默认值:0 System.out.println(one[1]);//打印数组one中索引编号1对应的元素的值,默认值:0 //把索引编号0对应的元素修改成100 one[0] = 100;//把数字100存储到数组one中索引编号为0的元素中 //把索引编号1对应的元素修改成200 one[1] = 200;//把数字200存储到数组one中索引编号为1的元素中 System.out.println(one);//数组名称: 数组在堆内存空间的地址值,16进制的整数数字: [I@1540e19d System.out.println(one[0]);//打印数组one中索引编号0对应的元素的值:100 System.out.println(one[1]);//打印数组one中索引编号1对应的元素的值:200 } } ~~~ ##### 图解: ![](https://img.kancloud.cn/af/c2/afc2ede045666448d8011b52e9b867fb_1285x535.png) ##### 2.3 两个数组内存图 ~~~ /* 两个数组的内存图解 1.数组名称: 数组在堆内存空间的地址值,16进制的整数数字 2.注意: (1)数组变量保存数组在堆内存中的地址值,通过地址值找到对应的数组 (2)数组元素都有索引编号,通过索引编号找到对应的元素 有两个数组,相当有有两套房子 一套是北京延庆两居室的房子,one是打开北京延庆两居室的房子的钥匙 一套是北京平谷两居室的房子,two是打开北京平谷两居室的房子的钥匙 你拿着钥匙one: 只能打开北京延庆两居室的房子 你的对象拿着钥匙two: 只能打开北京平谷两居室的房子 */ public class Demo02TwoArray { public static void main(String[] args) { //创建int类型数组one,长度为2 int[] one = new int[2];//你在北京延庆购买了一套两居室的房子,one就是打开这套房子的钥匙 System.out.println(one); System.out.println(one[0]); System.out.println(one[1]); one[0] = 100; one[1] = 200; System.out.println(one[0]); System.out.println(one[1]); System.out.println("--------------"); //创建int类型数组two,长度为2 int[] two = new int[2];//你在北京平谷购买了一套两居室的房子,two就是打开这套房子的钥匙 System.out.println(two); System.out.println(two[0]); System.out.println(two[1]); two[0] = 1000; two[1] = 2000; System.out.println(two[0]); System.out.println(two[1]); } } ~~~ ##### 图解:省略,就是把一个对象的内存图复制两份,每个数组之间没有任何关系 ##### 2.4 两个变量指向一个数组 ~~~ /* 一个数组两个引用(名称)的内存图解 1.数组名称: 数组在堆内存空间的地址值,16进制的整数数字 2.在使用数组名称进行赋值时,传递的都是数组在内存空间的地址值 3.注意: (1)数组变量保存数组在堆内存中的地址值,通过地址值找到对应的数组 (2)数组元素都有索引编号,通过索引编号找到对应的元素 数组变量名one中保存的是数组在堆内存空间的地址值,把one的值赋值给新的数组变量two, 导致数组变量名one和two保存相同的地址值,操作的是堆内存空间的同一个数组 one相当于是打开北京延庆两居室的房子的钥匙,现在通过钥匙one又配了一个新的钥匙two 此时: 钥匙one和two打开的都是北京延庆两居室的房子 钥匙one: 你自己拿着 钥匙two: 你对象拿着 注意: 1.数组变量保存数组在堆内存空间的地址值 2.使用数组变量进行赋值时,传递的是地址值 3.one保存数组在堆内存空间的地址值 把one赋值给新的数组变量two之后, 导致one和two保存相同的地址值,操作的 是同一个数组,不管通过one还是two修改 数组,之后再通过one和two看到的一定是 修改后的 */ public class Demo03SameArray { public static void main(String[] args) { //创建int类型数组one,长度为2 int[] one = new int[2];//你在北京延庆购买了一套两居室的房子,one就是打开这套房子的钥匙 one[0] = 100; /* 数组变量名one中保存的是数组在堆内存空间的地址值,把one的值赋值给新的数组变量two, 导致数组变量名one和two保存相同的地址值,操作的是堆内存空间的同一个数组 one相当于是打开北京延庆两居室的房子的钥匙,现在通过钥匙one又配了一个新的钥匙two 此时: 钥匙one和two打开的都是北京延庆两居室的房子 钥匙one: 你自己拿着 钥匙two: 你对象拿着 */ int[] two = one; two[0] = 1000; System.out.println(one[0]);//1000 System.out.println(two[0]);//1000 System.out.println(one);//[I@1540e19d System.out.println(two);//[I@1540e19d } } ~~~ ##### 图解: ![](https://img.kancloud.cn/69/c2/69c2039ee13ed2182f71c1fed3751988_1293x536.png) ### 第三章 数组操作的常见问题【了解】 ##### 3.1 数组越界异常 ~~~ 数组操作的常见问题一: 数组索引越界(超出了范围)异常 1.问题描述: java中使用java.lang.ArrayIndexOutOfBoundsException类来描述索引越界异常 2.产生原因: 使用int数字作为索引编号时,该索引编号在数组中是不存在的 索引编号范围: 从0开始 到 最大值 ( 数组长度 减 1 one.length - 1 ) 3.解决方案: 找到索引越界的数字,进行修改,不让该数字超出数组元素的索引范围 ~~~ ~~~ public class Demo01ArrayProblem { public static void main(String[] args) { //创建int数组one,并初始化 int[] one = new int[]{100, 200};//100编号是0,200的编号是1 System.out.println(one);//地址值: [I@1540e19d System.out.println(one[0]);//100 System.out.println(one[1]);//200 //System.out.println(one[2]);//索引2不存在: 程序出现问题,停止了 报出数组索引越界异常 System.out.println("main...end..."); } } ~~~ 图解: ![](https://img.kancloud.cn/59/64/5964aa21364538867960524617ff8b86_1289x534.png) ##### 3.2 数组空指针异常 ~~~ 数组操作的常见问题二: 空指针异常 1.问题描述: java中使用java.lang.NullPointerException类来描述空指针异常 2.产生原因: null是引用类型的空常量,可以赋值给任意引用类型的变量,一旦把null赋值给引用类型变量后, 说明该变量不再指向堆内存中的任何空间,也就不能操作堆内存空间的内容 null是引用类型的空常量,一旦把null赋值给数组变量后, 说明该数组变量不再指向堆内存空间中的任何数组, 也就不能再访问数组元素了,只要访问就会报出空指针异常 3.解决方案: (1)找到引用变量是null的地方,进行修改,不让它是null,让它指向堆内存中的一个具体的数组 (2)不使用值为null的引用变量访问堆内存空间的内容 ~~~ ~~~ public class Demo02ArrayProblem { public static void main(String[] args) { //创建int数组one,并初始化 int[] one = new int[]{100, 200};//100编号是0,200的编号是1 System.out.println(one);//地址值: [I@1540e19d System.out.println(one[0]);//100 System.out.println(one[1]);//200 one = null; System.out.println(one);//null //System.out.println(one[0]);//one的值是null,不能访问数组元素: 报出空指针异常 System.out.println("main...end..."); } } ~~~ ##### 图解: ![](https://img.kancloud.cn/ba/ed/baeda9bd2a76ad1b30a49b33765aa82a_1293x531.png) ### 第四章 数组练习【重点】 ##### 4.1 数组遍历 ~~~ 数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。 public class Demo01ArrayEach { public static void main(String[] args) { //创建int数组array,并初始化 int[] array = {100, 200, 300}; System.out.println(array);//地址值 System.out.println(array[0]);//100 System.out.println(array[1]);//200 System.out.println(array[2]);//300 System.out.println("----------------"); //以上三行代码重复,只有作为索引编号的数字0,1,2是不同的,可以使用for循环获取作为索引编号的数字0,1,2 for (int i = 0; i < 3; i++) { //System.out.println("索引编号: "+i+" 对应数组的元素值: "+array[i]); System.out.println(array[i]); } System.out.println("----------------"); //以上for循环,数字3写死了,其实数字3可以使用数组长度(数组名称.length)代替 for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } System.out.println("----------------"); for (int i = 0; i <= array.length - 1; i++) { System.out.println(array[i]); } } } ~~~ ##### 4.2 求三个int数字的最大值 ~~~ 需求: 求三个int数字的最大值 实现步骤: 1.定义三个int变量a,b,c,并分别初始化 2.假设变量a的值是最大的,保存到int变量max中 3.判断如果b的值 大于 max,说明max中已经不是最大的 3.1 把b的值赋值给max 4.判断如果c的值 大于 max,说明max中已经不是最大的 4.1 把c的值赋值给max 5.打印max的值 public class Demo02VarMax { public static void main(String[] args) { //1.定义三个int变量a,b,c,并分别初始化 int a = 100, b = 200, c = 300; //2.假设变量a的值是最大的,保存到int变量max中 int max = a; //3.判断如果b的值 大于 max,说明max中已经不是最大的 if(b > max) { //3.1 把b的值赋值给max max = b; } //4.判断如果c的值 大于 max,说明max中已经不是最大的 if (c > max) { //4.1 把c的值赋值给max max = c; } //5.打印max的值 System.out.println("最大值: "+max); } } ~~~ 图解: ![](https://img.kancloud.cn/78/4f/784ffc47e836ca039a6289fc0a376563_1098x466.png) ##### 4.3 数组获取最大值元素 ~~~ 需求: 求int数组元素最大值 实现步骤: 1.创建int数组array,并初始化 2.假设索引为0的元素是最大的,保存到int变量max中 3.使用for循环依次获取后面的(从索引1开始)每个元素 3.1如果当前元素值 大于 max 说明max中已经不是最大的了 3.2把当前元素赋值给max 4.for循环结束,打印max ~~~ ~~~ public class Demo03ArrayMax { public static void main(String[] args) { //1.创建int数组array,并初始化 int[] array = {5, 15, 2000, 10000, 100, 4000}; //2.假设索引为0的元素是最大的,保存到int变量max中 int max = array[0]; //3.使用for循环依次获取后面的(从索引1开始)每个元素 for (int i = 1; i < array.length; i++) { //3.1如果当前元素值 大于 max 说明max中已经不是最大的了 if(array[i] > max) { //3.2把当前元素赋值给max max = array[i]; } } //4.for循环结束,打印max System.out.println("数组元素最大值: "+max); } } ~~~ ##### 图解分析: ![](https://img.kancloud.cn/b0/63/b0632d0d81c261b65d00ef5bbb02a93e_1284x521.png) ##### 执行流程: ![](https://img.kancloud.cn/22/c4/22c4f3f4a7032d12bb3c14cb9714e96e_1242x465.png) ##### 总结 ~~~ 能够知道数组变量的定义格式 int[] array; int array2[]; 能够使用两种方式完成数组元素的初始化 1.动态初始化: 指定数组长度 int[] array = new int[3] 2.标准格式静态初始化: 指定元素 int[] array = new int[]{10,20,30}; 3.简化格式静态初始化: 指定元素 int[] array = {10,20,30}; 能够知道数组在内存中的初始化过程(了解) 能够完成数组的遍历操作 int[] array = {10,20,30}; for(int i = 0;i < array.length;i++) { sout(array[i]); } for(int i = 0;i <= array.length-1;i++) { sout(array[i]); } 能够完成数组的获取最值操作 ~~~