Java语言基础(五)数组

    技术2022-07-12  73

    Java语言基础(五)

    五、数组及其应用5.1 一维数组的基本概念5.2 一维数组的声明和使用5.3 一维数组的初始化5.4 内存结构分析(1)栈区(2)堆区(3)变量和数组的存储方式 5.5 一维数组的增删改查5.6 一维数组的优缺点优点缺点 5.7 一维数组之间的元素拷贝(笔试考点)5.8 一维数组案例案例1:一维数组统计次数案例2:数组实现成绩的录入和打印 5.9 数组工具类5.10 二维数组的基本概念(了解)5.11 二维数组的声明和使用5.12 二维数组的考点5.13 案例:二维数组与杨辉三角总结

    五、数组及其应用

    5.1 一维数组的基本概念

    当需要在Java程序中记录单个数据内容时,则声明一个变量即可当需要在Java程序中记录多个类型相同的数据内容时,则声明一个一维数组即可, 一维数组本质上就是在内存空间中申请一段连续的存储单元数组是相同数据类型的多个元素的容器,元素按线性顺序排列,在Java语言中体现为一种引用数据类型

    5.2 一维数组的声明和使用

    语法格式 数据类型[ ] 数组名称 = new 数据类型[ 数组长度 ] // new 是关键字,表示新建

    如:int[ ] array = new int[10] 数组的另一种声明方式: int array[ ] = new int[10] // 这种方式是延续C++的声明方法,不推荐使用,因为容易跟变量声明混淆

    调用数组的 length属性可以获取数组长度

    array.length

    通过下标的方式访问数组的每个元素 注:数组下标从 0 开始,对于长度为n的数组,下标范围是 0 ~ n-1

    int[0]、int[1] …

    引用下标超过一维数组的下标范围时的报错:java.lang.ArrayIndexOutOfBoundsException 对比 0作除数时的报错 :java.lang.ArithmeticException: / by zero

    5.3 一维数组的初始化

    (1)基本类型的数组(数据元素为基本类型)创建后,其元素的初始值(默认值): byte、short、char、int、long 初始值为 0float、double 初始值为 0.0boolean 初始值为 false (2)也可以在数组声明的同时进行初始化(静态方式的简化版),具体如下: 数据类型[ ] 数组名称 = {初始值1,初始值2,…}

    char[ ] array1 = {‘a’, ‘b’, ‘c’, ‘d’} boolean[ ] array2 = {false, false, true, false} 静态方式完整版: boolean[ ] array2 = new boolean[ ] {false, false, true, false} // 简化版省略了高亮部分

    5.4 内存结构分析

    (1)栈区

    栈用于存放程序运行过程当中所有的局部变量。一个运行的Java程序从开始到结束会有多次变量声明,也会有多次方法的调用(调用方法时可能会产生局部变量)JVM会为每个方法的调用在占中分配一个对应的空间(入栈),这个空间称为该方法的栈帧。一个栈帧对应一个正在调用的方法,栈帧中存储了该方法的参数、局部变量等数据。方法结束后就会释放内存(出栈)

    (2)堆区

    JVM会在其内存空间中开辟一个称为“堆”的存储空间,用于存储使用new关键字创建的数组和对象

    (3)变量和数组的存储方式

    声明变量时,直接存放在直接存放在栈区

    int num = 2;

    声明数组时,会将数组元素连续存储在堆区,而栈区会存放数组在堆区的地址信息

    int[ ] arr1 = new int[2]; 代码分析: 当执行等号左边的int[ ] arr1时,会在栈区申请一个内存空间 当执行等号右边的new int[2]时,会在堆区申请一个连续内存空间,并存储数组所有元素 当执行中间的赋值操作时,相当于把该数组在堆区的内存地址赋值给栈区申请到的内存空间 所以 System.out.println(arr1) 打印的是数组的地址(如0x10),而不是数组的所有元素

    5.5 一维数组的增删改查

    通过案例来实现以下功能 (1)声明和赋值 (2)插入 (3)删除 (4)查、改 /* 编程实现一维数组的增删查改操作 */ public class VarTest { public static void main(String[] args) { // 1.声明一个长度为5的元素类型为int的一维数组,打印数组中所有元素值 int[] arr = new int[5]; // 打印数组中所有元素值 //System.out.println(""); for(int i=0; i<arr.length; i++) { System.out.println("第" + (i+1) + "个元素是:" + arr[i]); } System.out.println("-------------------------"); // 2.使用元素11、22、33、44分别对数组中前四个元素赋值后再次打印 for(int i=0; i<=3; i++) { arr[i] = 11*(i+1); } for(int i=0; i<arr.length; i++) { System.out.println("第" + (i+1) + "个元素是:" + arr[i]); } System.out.println("-------------------------"); // 3.将元素55插入到下标为0的位置,原有元素向后移动,再打印所有元素值 for(int i=arr.length-1; i>=1; i--) { arr[i] = arr[i-1]; //System.out.println(i); } arr[0] = 55; for(int i=0; i<arr.length; i++) { System.out.println("第" + (i+1) + "个元素是:" + arr[i]); } System.out.println("-------------------------"); // 4.将元素55从数组中删除,删除方式为后续元素向前移动,最后位置置为0并打印 for(int i=0; i<arr.length-1; i++) { //System.out.println(i); arr[i] = arr[i+1]; } arr[arr.length-1] = 0; for(int i=0; i<arr.length; i++) { System.out.println("第" + (i+1) + "个元素是:" + arr[i]); } System.out.println("-------------------------"); // 5.查找数组中是否存在元素22,若存在则修改为220后再次打印所有元素 boolean isExist = false; for(int i=0; i<arr.length; i++) { if(22 == arr[i]) { arr[i] = 220; isExist = true; } } if(!isExist) { System.out.println("数组中不存在元素22!"); } else { for(int i=0; i<arr.length; i++) { System.out.println("第" + (i+1) + "个元素是:" + arr[i]); } } } }

    5.6 一维数组的优缺点

    优点

    可以直接通过下标(或索引)的方式访问指定位置的元素,速度很快

    缺点

    数组要求所有元素的类型相同数组要求内存空间连续,并长度固定(不能修改)增加和删除元素时可能会移动大量元素,效率低

    5.7 一维数组之间的元素拷贝(笔试考点)

    笔试考点:数组 arr、brr

    brr = arr 表示 arr 表示的地址赋值给brr,相当于让brr和arr指向了同一块堆区空间,有本质上就是改变指向而已

    /* 编程实现数组之间元素的拷贝 */ public class ArrayCopyTest { public static void main(String[] args) { // 1.声明一个初始值为11、22、33、44、55的一维数组 int[] arr = {11, 22, 33, 44, 55}; // 打印数组中的所有元素 System.out.print("第一个数组中的元素有:"); for(int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); // 11 22 33 44 55 } // 2.声明一个长度为3元素类型为int类型的一维数组 int[] brr = new int[3]; // 打印数组中的所有元素 System.out.print("第二个数组中的元素有:"); for(int i = 0; i < brr.length; i++) { System.out.print(brr[i] + " "); // 0 0 0 } // 3.将第一个数组中的中间3个元素赋值到第二个数组中 /* for(int i = 0; i < brr.length; i++) { brr[i] = arr[i+1]; } */ // 也可以直接使用Java官方提供的拷贝功能 // arraycopy​(Object src, int srcPos, Object dest, int destPos, int length) // 表示将数组arr中下标从1开始的3个元素拷贝到数组brr中下标从0开始的位置 System.arraycopy(arr, 1, brr, 0, 3); // 打印第二个数组中的所有元素 System.out.print("第二个数组中的元素有:"); for(int i = 0; i < brr.length; i++) { System.out.print(brr[i] + " "); // 22 33 44 } // 4.笔试考点 // 表示将变量arr的数值赋值给变量brr,覆盖变量brr中原来的数值 // 数组名arr的内存空间中存放的是数据在堆区中的内存地址信息,赋值后让brr变量中存放了arr所指向堆区的内存地址 // 也就是让brr和arr指向了同一块堆区空间,有本质上就是改变指向而已 brr = arr; // 打印第二个数组中的所有元素 System.out.print("第二个数组中的元素有:"); for(int i = 0; i < brr.length; i++) { System.out.print(brr[i] + " "); // 22 33 44 } System.out.println(); } }

    5.8 一维数组案例

    案例1:一维数组统计次数

    编程统计用户输入任意一个正整数中每个数字出现次数的统计并打印

    如:123123 => 1出现2次,2出现2次,3出现2次

    import java.util.Scanner; public class ArrayCountTest { public static void main(String[] args) { // 1.提示用户输入一个正整数并使用变量记录 System.out.println("请输入一个正整数:"); Scanner sc = new Scanner(System.in); int num = sc.nextInt(); // 2.准备一个长度为10元素类型int类型的一维数组,默认值为0 int[] arr = new int[10]; // 3.拆分正整数中的每个数字并统计到一维数组中 int temp = num; while(temp > 0) { arr[temp%10]++; temp /= 10; } // 4.打印最终的统计结果 for(int i = 0; i < arr.length; i++) { if(arr[i] > 0) { System.out.println("数字" + i + "出现了" + arr[i] + "次!"); } } } }

    案例2:数组实现成绩的录入和打印

    提示用户输入学生的人数以及每个学生的考试成绩并打印出来计算该班级的总分和平均分并打印出来 /* 编程使用数组来记录学生的考试成绩并打印 */ import java.util.Scanner; public class ArrayScoreTest { public static void main(String[] args) { // 1.提示用户输入学生的人数并使用变量记录 System.out.println("请输入学生的人数:"); Scanner sc = new Scanner(System.in); int num = sc.nextInt(); // 2.根据学生的人数来声明对应长度的数组负责记录学生的考试成绩 // 变长数组 : 主要指变量可以作为数组的长度,但绝不是数组的长度可以发生改变 int[] scores = new int[num]; // 3.提示用户输入每个学生的考试成绩并记录一维数组中 for(int i = 0; i < num; i++) { System.out.println("请输入第" + (i+1) + "个学生的考试成绩:"); scores[i] = sc.nextInt(); } // 4.打印所有学生的考试成绩 System.out.print("本班学生的考试成绩分别是:"); for(int i = 0; i < scores.length; i++) { System.out.print(scores[i] + " "); } System.out.println(); // 5.计算本班级学生的总分以及平均分并使用变量记录 int sum = 0; for(int i = 0; i < scores.length; i++) { sum += scores[i]; } double avg = sum*1.0 / num; // 打印最终的计算结果 System.out.println("本班级学生的总分是:" + sum + ",平均分是:" + avg); } }

    5.9 数组工具类

    java.util.Arrays类可以实现对数组中元素的遍历、查找、排序等注意:方法Arrays.binarySearch()调用前必须对数组进行排序

    5.10 二维数组的基本概念(了解)

    二维数组本质上就是由多个一维数组摞在一起组成的数组二维数组中的每个元素都是一维数组一维数组中的每个元素才是数据内容

    5.11 二维数组的声明和使用

    二维数组的内存空间是不连续的,其每个元素【一维数组】内存空间是连续的语法格式(初始化操作)

    方式一:数据类型 [ ] [ ] 数组名称 = new 数据类型[行数] [列数] 方式二:数据类型 [ ] [ ] 数组名称 = {{a1, a2, …}, {b1, b2, …}, …} // 静态方法的简化版 静态方法的完整版:数据类型 [ ] [ ] 数组名称 = new 数据类型[ ] [ ] {{a1, a2, …}, {b1, b2, …}, …}

    /* 编程实现二维数组的声明和使用 */ public class ArrayArrayTest { public static void main(String[] args) { // 1.声明一个具有2行3列元素类型为int类型的二维数组 int[][] arr1 = new int[2][3]; // 打印数组中的每个元素 // 使用外层for循环控制打印的行数 for(int i = 0; i < arr1.length; i++) { // 使用内层for循环控制打印的列数(注意此处j范围的表达,不要写成常量,因为每一列的长度可以不一样) for(int j = 0; j < arr1[i].length; j++) { System.out.print(arr1[i][j] + " "); // 全是0 } System.out.println(); } System.out.println("--------------------------------------------------"); // 2.实现二维数组中元素的赋值 int cnt = 1; // 使用外层for循环控制打印的行数 for(int i = 0; i < arr1.length; i++) { // 使用内层for循环控制打印的列数 for(int j = 0; j < arr1[i].length; j++) { arr1[i][j] = cnt++; } } // 使用外层for循环控制打印的行数 for(int i = 0; i < arr1.length; i++) { // 使用内层for循环控制打印的列数 for(int j = 0; j < arr1[i].length; j++) { System.out.print(arr1[i][j] + " "); // 1 2 3 4 5 6 } System.out.println(); } System.out.println("--------------------------------------------------"); // 3.二维数组元素的初始化操作 int[][] arr2 = {{11, 22, 33, 44}, {55, 66, 77, 88}}; // 使用外层for循环控制打印的行数 for(int i = 0; i < arr2.length; i++) { // 使用内层for循环控制打印的列数 for(int j = 0; j < arr2[i].length; j++) { System.out.print(arr2[i][j] + " "); // 11 22 33 44 55 66 77 88 } System.out.println(); } System.out.println("--------------------------------------------------"); // 4.考点 int[][] arr3 = new int[3][]; arr3[0] = new int[3]; arr3[1] = new int[4]; arr3[2] = new int[5]; } }

    5.12 二维数组的考点

    int [ ] [ ] arr1 = new int[3] [ ]; // 声明一个三行但不确定几列的二维数组 arr1[0] = new int[3]; // 每列的长度可以不一样 arr1[1] = new int[4]; arr1[2] = new int[5];

    5.13 案例:二维数组与杨辉三角

    /* 编程使用二维数组来实现杨辉三角的生成和遍历 */ import java.util.Scanner; public class ArrayArrayTriangleTest { public static void main(String[] args) { // 1.提示用户输入一个行数并使用变量记录 System.out.println("请输入一个行数:"); Scanner sc = new Scanner(System.in); int num = sc.nextInt(); // 2.根据用户输入的行数来声明对应的二维数组 int[][] arr = new int[num][]; // 3.针对二维数组中的每个元素进行初始化,使用双重for循环 // 使用外层for循环控制二维数组的行下标 for(int i = 0; i < num; i++) { // 针对二维数组中的每一行进行内存空间的申请 arr[i] = new int[i+1]; // 使用内层for循环控制二维数组的列下标 for(int j = 0; j <= i; j++) { // 当列下标为0或者列下标与当前行的行下标相等时,则对应位置的元素就是1 if(0 == j || i == j) { arr[i][j] = 1; } else { // 否则对应位置的元素就是上一行当前列的元素加上上一行前一列的元素 arr[i][j] = arr[i-1][j] + arr[i-1][j-1]; } } } // 4.打印最终生成的结果 for(int i = 0; i < num; i++) { for(int j = 0; j <= i; j++) { System.out.print(arr[i][j] + " "); } System.out.println(); } } }

    总结

    Processed: 0.013, SQL: 10