Java-基础篇【数组、方法】
1:数组 引用类型,不是基本数据类型
2:静态初始化数组
package com.itheima.create; /** 数组就是用来存储一批同种类型数据的容器 目标:学会使用静态初始化的方式定义数组 数组定义: 静态初始化数组:数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,...} double[] scores = new double[]{99.5, 88.0, 75.5}; double[] scores = {99.5, 88.0, 75.5}; double scores[] = {99.5, 88.0, 75.5}; 数组存储原理: 内存中开辟一个区域存储数组变量 ages 后面 new出来的对象也存在一个区域存放数据,连续的区域:存放 12, 24, 36 这块区域再内存中有个地址,地址xxx001, = 等号从右往左执行,把地址交给左边数组变量 ages这里进行存储 数组名称根据数组地址找数组对象,找到地址是首地址就可以访问数据了 数组名称age存储的是数组对象的地址 数组变量名中存储的是数组在内存中的地址【起始地址】,数组是引用类型 引用类型:存储的是对象的地址,根据地址引用对象 基本数据类型:存储的是数据 */ public class ArrayDemo1 { public static void main(String[] args) { // 数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,...} // double[] scores = new double[]{99.5, 88.0, 75.5}; double[] scores = {99.5, 88.0, 75.5}; // 简化写法 // int[] ages = new int[]{12, 24, 36}; int[] ages = {12, 24, 36}; // String[] names = new String[]{"牛二", "全蛋儿", "老王"}; String[] names = {"牛二", "全蛋儿", "老王"}; System.out.println(scores); // [D@1b6d3586 D:double类型 [:表示数组 @:在哪里 1b6d3586:16进制地址 } }
package com.itheima.create; /** 目标:学会访问数组的元素 索引:0,1,2 length:长度 数组名称[索引] int[] arr = {12, 24, 36}; System.out.println(arr[2]) arr:找到数组对象,找的是起始地址 0:找到具体原生 System.out.println(arr.length); 访问数组长度 数组最大长度: length - 1 需要里面有元素 */ public class ArrayDemo2 { public static void main(String[] args) { int[] ages = {12, 24, 36}; // 0 1 2 // 取值: 数组名称[索引] System.out.println(ages[0]); System.out.println(ages[1]); System.out.println(ages[2]); // 赋值:数组名称[索引] = 数据; ages[2] = 100; System.out.println(ages[2]); // 访问数组的长度 System.out.println(ages.length); // int[] arr = {}; // System.out.println(arr.length - 1); } }
package com.itheima.create; /** 目标:理解数组的注意事项 */ public class ArrayAttentionDemo3 { public static void main(String[] args) { int[] ages = {11, 23, 45}; // 1、数据类型[] 数组名称 也可以写成 数据类型 数组名称[] int ages1[] = {11, 23, 45}; // 写法和上一致 // String[] names = {"西门吹雪", "独孤求败", 23}; // 错误的 // 2、什么类型的数组只能存放什么类型的元素 int[] ages2 = {11, 23, 45}; // 3、数组一旦定义出来之后,类型和长度就固定了 System.out.println(ages2[3]); // 报错! 长度固定是3了不能访问第4个元素!! } }
3:数组的动态初始化
package com.itheima.create; /** 目标:学会动态初始化数组的定义和使用。 数组的动态初始化: 定义数组的时候只确定元素的类型和数组的长度,之后再存入具体数据 ---一开始不存入具体数据 数据类型[] 数组名 = new 数据类型[长度]; int[] arr = new int[3]; 赋值: arr[0] = 10; System.out.println(arr[0]); arr变量空间:存储数组首元素地址 数组对象:默认都放 0,分配索引,没有确定的数据都使用默认值0,和 数组的静态初始化差不多 */ public class ArrayDemo4 { public static void main(String[] args) { double[] scores = new double[3]; // [0.0, 0.0, 0.0] // 0 1 2 // 赋值 scores[0] = 99.5; System.out.println(scores[0]); System.out.println(scores[2]); String[] names = new String[90]; names[0] = "迪丽热巴"; names[2] = "马尔扎哈"; System.out.println(names[0]); System.out.println(names[1]); // null System.out.println(names[2]); } }
package com.itheima.create; /** * 目标:掌握动态初始化元素默认值的规则。 * */ public class ArrayDemo5 { public static void main(String[] args) { // 1、整型数组的元素默认值都是0 int[] arr = new int[10]; System.out.println(arr[0]); System.out.println(arr[9]); // 2、字符数组的元素默认值是多少呢? 0 char[] chars = new char[100]; System.out.println((int)chars[0]); System.out.println((int)chars[99]); // 3、浮点型数组的元素默认值是0.0 double[] scores = new double[90]; System.out.println(scores[0]); System.out.println(scores[89]); // 4、布尔类型的数组 boolean[] booleans = new boolean[100]; System.out.println(booleans[0]); System.out.println(booleans[99]); // 5、引用类型的数组 String[] names = new String[90]; System.out.println(names[0]); System.out.println(names[89]); // int[] arrs = new int[3]{30, 40, 50}; int[] a = {1,2,3}; int[] b = {1,2,3}; System.out.println(a); System.out.println(b); } }
4:数组的遍历
package com.itheima.traverse; import java.util.Arrays; /** 目标:学会进行数组元素的遍历 循环的快速补全: arr.for i 回车自动补全 arr[i].sou 回车自动补全 */ public class ArrayDemo { public static void main(String[] args) { // 目标:学会进行数组元素的遍历 int[] arr = new int[]{12, 24, 12, 48, 98}; // int arr[] = {12, 24, 12, 48, 98}; // 0 1 2 3 4 // 原始遍历方式 // 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]); // for (int i = 0; i < 5; i++) { // System.out.println(arr[i]); // } // 终极数组遍历形式 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } for (int i = 0; i < arr.length; i++) { } } }
5:数组使用简单练习
package com.itheima.demo; /** 需求:数组元素求和 */ public class Test1 { public static void main(String[] args) { int[] money = {16, 32, 8, 100, 78}; // 1、把这些数据拿到程序中使用数组记住,静态初始化数组 int sum = 0; // 3、定义一个求和变量累加数组的元素值 for (int i = 0; i < money.length; i++) { // 2、遍历数组中的每个元素 sum += money[i]; // 拿到每个元素值累加 } System.out.println("数组的元素和是:" + sum); // 4、输出求和变量即可 } }
package com.itheima.demo; /** 需求:数组元素求最值。 */ public class Test2 { public static void main(String[] args) { int[] faceScore = {15, 9000, 10000, 20000, 9500, -5}; // 1、定义一个静态初始化的数组,存储一批颜值。 // 0 1 2 3 4 5 int max = faceScore[0]; // 2、定义一个变量用于存储最大值元素,建议使用第一个元素作为参照 // 不要使用 0作为 参照,万一 0真的是最大值里面的列表里的值都是负数,那么找不出列表里的最大值了 // 参照值一定来源于数组,一般使用第一个元组作为参照 for (int i = 1; i < faceScore.length; i++) { // 3、遍历数组的每个元素,依次与最大值变量的数据比较,若较大,则替换。 if(faceScore[i] > max){ max = faceScore[i]; } } System.out.println("数组的最大值是:" + max); // 4、输出最大值变量存储的数据即可。 } }
package com.itheima.demo; import java.util.Random; import java.util.Scanner; /** 需求:5个 1-20之间的随机数,让用户猜测,猜中要提示猜中,还要输出该数据在数组中第一次出现的索引,并打印数组的内容出来。 没有猜中继续。 不知道 5个数据的值,使用动态初始化数组,然后把5个值桩进去 死循环让用户没猜到一直猜 */ public class Test3 { public static void main(String[] args) { int[] data = new int[5]; // 1、定义一个动态初始化的数组存储5个随机的1-20之间的数据 Random r = new Random(); // 2、动态的生成5个1-20之间的随机数并存入到数组中去。 循环赋值 for (int i = 0; i < data.length; i++) { // i = 0 1 2 3 4 data[i] = r.nextInt(20) + 1; // 1-20 需要 +1 } Scanner sc = new Scanner(System.in); OUT: while (true) { // 3、使用一个死循环让用户进行猜测 System.out.println("请您输入一个1-20之间的整数进行猜测:"); int guessData = sc.nextInt(); // 4、遍历数组中的每个数据,看是否有数据与猜测的数据相同,相同代表猜中了,给出提示 for (int i = 0; i < data.length; i++) { if(data[i] == guessData){ System.out.println("您已经猜中了该数据,运气不错了!您猜中的数据索引是:" + i); break OUT; // 结束了整个死循环,代表游戏结束了! // break 只会结束找元素这个 for 循环,结束不了整个外部循环 // break OUT 结束整个 while 死循环 } } System.out.println("当前猜测的数据在数组中不存在,请重新猜测!"); } for (int i = 0; i < data.length; i++) { // 5、输出数组的全部元素,让用户看到自己确实是猜中了某个数据。 System.out.print(data[i] + "\t"); } } }
package com.itheima.demo; import java.util.Random; import java.util.Scanner; /** 目标:键盘录入一组工号,最终要随机输出一组出来作为排名 动态初始化: */ public class Test4 { public static void main(String[] args) { int[] codes = new int[5]; // 1、动态初始化一个数组,存储5个工号 Scanner sc = new Scanner(System.in); // 2、定义一个循环,循环5次,依次录入一个工号存入对应的位置 for (int i = 0; i < codes.length; i++) { System.out.println("请您输入第" + (i + 1) + "个员工的工号:"); // 正式录入工号 int code = sc.nextInt(); codes[i] = code; // 存入到数组中去 } // 3、遍历数组中的每个元素,然后随机一个索引出来,让该元素与随机索引位置处的元素值进行交换(本节的重点) // codes = [12, 36, 28, 45, 99] Random r = new Random(); for (int i = 0; i < codes.length; i++) { // 当前遍历的元素值:codes[i] // 随机一个索引位置出来:codes[index] int index = r.nextInt(codes.length); // codes.length数组长度 // 定义一个临时变量存储index位置处的值 int temp = codes[index]; codes[index] = codes[i]; codes[i] = temp; } // 4、遍历数组元素输出就是随机排名的结果 for (int i = 0; i < codes.length; i++) { System.out.print(codes[i] + "\t"); } } }
package com.itheima.demo; /** 数组排序: 冒泡排序 冒泡排序: 每次从数组中找出最大值放在数组的后面去 */ public class Test5 { public static void main(String[] args) { int[] arr = {5, 2, 3, 1}; // 1、定义一个数组,存储一些数据啊 // 0 1 2 3 for (int i = 0; i < arr.length - 1; i++) { // 2、定义一个循环控制比较的轮数:控制比较几轮, // i == 0 比较的次数 3 j = 0 1 2 // i == 1 比较的次数 2 j = 0 1 // i == 2 比较的次数 1 j = 0 for (int j = 0; j < arr.length - i - 1; j++) { // 3、定义一个循环控制每轮比较的次数,占位 // 判断j当前位置的元素值 是否 大于后一个位置 若较大 则交换 if(arr[j] > arr[j+1]) { int temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; } } } for (int i = 0; i < arr.length; i++) { // 遍历数组内容输出 System.out.print(arr[i] + "\t"); } } }
package com.itheima.demo; /** * 数组(基本面试题):判断两个数组数据是否相等 * */ public class Test6 { public static void main(String[] args) { int[] arr1 = {10, 20, 30}; int[] arr2 = {11, 20, 30}; // 内容 个数完全一样。 if(arr1 == arr2){ System.out.println("两个数组相等!"); }else{ // 地址不同,比较内容是否相同! if(arr1.length == arr2.length){ // 编程思想:定义一个信号位,默认认为是相等的。 boolean flag = true; for (int i = 0; i < arr1.length; i++) { if(arr1[i] != arr2[i]){ System.out.println("两个数组不相等!"); flag = false; // 表示不相等了 break; } } if(flag){ System.out.println("两个数组相等!!"); } }else { System.out.println("两个数组不相等!"); } } } }
package com.itheima.demo; public class Test7 { public static void main(String[] args) { // 1 1 // 2 1 // 3 2 // 4 3 // 5 5 // 6 8 // ... // ... // ... // 20 int[] numbers = new int[20]; numbers[0] = 1; numbers[1] = 1; for (int i = 2; i < numbers.length; i++) { numbers[i] = numbers[i-1] + numbers[i-2]; } for (int i = 0; i < numbers.length; i++) { System.out.println((i+1) +"月兔子数:" + numbers[i]); } } }
5:Java内存分配介绍
6:实例化一个数组java内存分配
package com.itheima.memory; /** Java 内存分配介绍 栈: 堆: 方法区: 本地方法栈 寄存器 java内存区域分成 5 块区域:不同区域干不同事情,方便维护和性能 栈内存: 方法运行时所进入的内存,变量也是在这里 main方法提到 栈内存里来运行的,main方法里面的一些变量也是放在栈内存 堆内存: new 出来的东西会在这块内存中开辟空间并产生地址 所有 new 出来的东西都放在堆内存的,new 出来的东西叫对象 方法区: 字节码文件加载时进入的内存,代码编译后产出一个class文件,代码执行过程中 class文件数据加载到这来 主要这3块区域配合执行java程序 代码执行原理: 1:文件编译成class 文件,加载到 方法区 2:main 方法变量 提取到 栈内存区域 ,开始执行代码 3:变量 a 也是存储在 栈内存 ,存储10,所以 打印 a 变量能直接输出 4:arr数组引用类型变量,arr存储在栈内存 ,存储的是 new int[]{11, 22, 33}在堆内存中的内存地址 arr这个变量就指向了数组对象堆内存中的数组对象的起始位置【第一个位置】 5:new int[]{11, 22, 33}; new类型对象会在堆内存里面开辟一个数组的空间,这里面3块区域组成一个数组,每个区域大小一样,有索引,有长度 堆内存的对象区域有自己的地址 6:arr找到数组对象起始位置,索引 0,1找到索引位置的值, 下面类似找区域位置 数组的内存图 */ public class ArrayDemo1 { public static void main(String[] args) { int a = 12; System.out.println("a"); // 基本类型输出的都是数据【存储的就是数据】 int[] arr = new int[]{11, 22, 33}; arr[0] = 44; arr[1] = 55; arr[2] = 66; System.out.println(arr); // a[I@4b67cf4d 引用数据类型:数组这里存储右边对象数组的地址 System.out.println(arr[0]); System.out.println(arr[1]); System.out.println(arr[2]); } }
7:两个数组变量指向同一个数组内存图
package com.itheima.memory; /** 两个变量指向同一个数组: */ public class ArrayDemo2 { public static void main(String[] args) { int[] arr1 = new int[]{11, 22, 33}; int[] arr2 = arr1; // arr2 和 arr1 这两个数组变量 指向同一个数组对象【内存地址】 // arr1 把数组的地址 赋值给了 arr2 System.out.println(arr1); System.out.println(arr2); arr2[2] = 100; System.out.println(arr1[2]); // 100 System.out.println(arr2[2]); // 100 } }
8:数组常见问题
9:IDEA的Dug工具
10:键盘录入
下载API文档:http://www.oracle.com/technetwork/java/javase/downloads/index.html
11:方法定义的格式
package com.itheima.create; /** 目标:能够说出使用方法的优点: 1、可以提高代码的复用性和开发效率。 2、让程序的逻辑更清晰。 方法定义格式: 修饰符 返回值类型 方法名( 形参列表 ){ 方法体代码(需要执行的功能代码) return 返回值; } 方法的修饰符统一都是:public static 类的修饰符:public class 方法内部返回一个浮点数:double 方法的名称:sum int a, int b:形参列表,逗号隔开,可以不同类型,不能赋值,只能接受数据 方法定义后需要调用才会执行 :double c2 = sum(10, 50); */ public class MethodDemo1 { public static void main(String[] args) { double c1 = sum(10, 30); // 张工 System.out.println(c1); double c2 = sum(10, 50); // 徐工 System.out.println(c2); } public static double sum(int a, int b){ // int:表示返回一个整数 double c = a + b ; // 方法执行代码 return c; // 返回值 } }
package com.itheima.create; /** 目标:学习方法的完整定义格式,并理解其调用和执行流程 执行流程: 1:执行等号右边,add(100, 200); 找到函数 public static int add,100传递给a,200传递给b 2:执行add函数 方法执行代码,算出c的值300 3:300返回出去,赋值给rs 方法定义: 方法的修饰符:暂时都使用public static 修饰。 方法申明了具体的返回值类型,内部必须使用return返回对应类型的数据。 形参列表可以有多个,甚至可以没有; 如果有多个形参,多个形参必须用“,”隔开,且不能给初始化值 */ public class MethodDemo2 { public static void main(String[] args) { int rs = add(100, 200); System.out.println("和是:" + rs); System.out.println("-----------------"); int rs1 = add(200, 300); System.out.println("和是:" + rs1); } public static int add(int a, int b){ int c = a + b; return c; } }
12:方法的调用流程--Debug
13:方法格式的注意点
14:void的使用:方法没有返回值时候使用void修饰
package com.itheima.create; /** 方法定义时:返回值类型、形参列表可以按照需求进行填写 void:无返回值类型,没有返回值也要写这个 void 还可以不接参数 如果方法不需要返回结果,返回值类型必须申明成void(无返回值), 此时方法内部不可以使用return返回数据 方法如果没有参数,或者返回值类型申明为void可以称为无参数、无返回值的方法,依次类推 */ public class MethodDemo3 { public static void main(String[] args) { // 目标:学会方法定义的其他形式,并理解其流程 print(); System.out.println("------------"); print(); } public static void print(){ // 无参数无返回值的方法 返回值类型这里使用 void: for (int i =0; i < 3; i++) { System.out.println("Hello World"); // ctrl + alt +t 快捷输入 } } }
15:编写方法使用常见的问题
package com.itheima.create; /** 方法的编写顺序无所谓:自己定义的方法写在main方法的上面和下面没有关系 方法与方法之间是平级关系,不能嵌套定义:方法不能放在 main方法里面,不然无法调用 方法的返回值类型为void(无返回值),方法内则不能使用return返回数据, 如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据。 return语句下面,不能编写代码,因为永远执行不到,属于无效的代码:return 后方法就执行结束了 方法不调用就不执行, 调用时必须严格匹配方法的参数情况。 有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用。 变量接收结果:int rs = sum(100, 900); 直接输出调用:System.out.println(rs); 直接调用:sum(3000, 5000); */ public class MethodAttentionDemo4 { public static void main(String[] args) { // 方法的编写顺序无所谓。 System.out.println(sum(10, 20)); // 方法与方法之间是平级关系,不能嵌套定义。 // 方法的返回值类型为void(无返回值),方法内则不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据。 // return语句下面,不能编写代码,因为永远执行不到,属于无效的代码。 // 方法不调用就不执行, 调用时必须严格匹配方法的参数情况。 print(); // 有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用一下。 int rs = sum(100, 900); System.out.println(rs); // 输出调用 System.out.println(sum(1000, 2000)); // 直接调用(只是调用方法,让方法跑一下,但是方法返回的结果它不要了!) sum(3000, 5000); // 无返回值方法的调用只能直接调用一下。 print(); } public static int sum(int a, int b){ return a + b; // System.out.println("学习方法!"); } public static void print(){ System.out.println("Hello World"); System.out.println("Hello World"); System.out.println("Hello World"); // return 21; // 报错的 } }
16:定义方法的技巧说明
package com.itheima.demo; /** 需求:使用方法计算1-n的和并返回 1:根据格式编写方法 ----> 因n不固定,故方法需要声明形参接收;要返回结果,还需申明返回值类型 2:方法内部使用 for 循环计算出 1-n 的和并返回。 定义方法时真正需要关注的就两点: 1、分析方法是否需要申明返回值类型; 2、分析方法是否需要接收参数。 理解方法的内存运行机制 class文件提取到方法区里: main 方法代码 add 方法代码 先执行main方法,默认启动方法 main方法启动后会提取到栈里执行, 执行main的时候先执行:sum(5),需要暂停,需要找sum方法,把sum方法加载到栈内存, 把参数5 传递给sum方法的参数n,sum方法开辟变量空间存储5这个数据, 执行sum里的代码,算出sum的值,把sum的值直接返回到add这里 add方法执行完成后从栈内存丢出去, main方法继续执行拿到结果输出,main方法执行完了也从栈内存中丢出去 程序执行完成 */ public class Test1 { public static void main(String[] args) { System.out.println("1-5的和是:" + sum(5)); System.out.println("--------------------"); System.out.println("1-100的和是:" + sum(100)); } public static int sum(int n){ int sum = 0; for (int i = 1; i <= n ; i++) { sum += i; } return sum; } }
package com.itheima.demo; /** 需求:判断一个整数是奇数还是偶数 并进行结果的输出 使用方法完成 1:因要传入数据给方法,方法需要声明形参接收 2:方法内部使用if语句判断,并输出对应的结论 */ public class Test2 { public static void main(String[] args) { check(11); System.out.println("-------------"); check(100); } public static void check(int number) { if(number % 2 == 0){ // 对2求余,余数为0 System.out.println(number + "是偶数"); }else { System.out.println(number + "是奇数"); } } }
package com.itheima.demo; /** 需求:使用方法,支持找出任意整型数组的最大值返回。 方法分析: 1:要返回最大值,需要申明返回值类型 2:需要接收数组, 需要申明形参列表 3:方法内部找出数组的最大值并返回 ages指向数组对象的地址。然后ages把数组地址传递给方法里的 arr, arr和 ages两个数组变量指向同一个对象,找出最大值 然后返回 */ public class Test3 { public static void main(String[] args) { int[] ages = {23, 19, 25, 78, 34}; // 整形数组 int max = getArrayMaxData(ages); System.out.println("最大值数据是:" + max); System.out.println("-------------------"); int[] ages1 = {31, 21, 99, 78, 34}; int max1 = getArrayMaxData(ages1); System.out.println("最大值数据是:" + max1); } public static int getArrayMaxData(int[] arr){ // 找出数组的最大值返回,参数:数组类型 int[]:数组类型 接受的参数是数组对象的地址 int max = arr[0]; for (int i = 1; i < arr.length; i++) { // 遍历数组的每个元素与最大值的数据进行比较,若较大则替换 if(arr[i] > max){ max = arr[i]; } } return max; } }
17:方法调用的流程--内存解析
方法是放在方法区中的,被调用的时候,需要进入到栈内存中运行
package com.itheima.demo; /* 目标:理解方法的内存运行机制 方法没有被调用的时候,在方法 区中的字节码 文件中存放 方法被调用的时候,需要进入 栈内存中运行 方法区加载class文件:产生4个方法 main study sleep eat main方法提取到 栈 内存 里,main调用 study加载study,然study 加载eat, eat输出,eat执行完成从栈推出,然study执行输出后调用sleep,sleep加载到栈运行后退出去 study执行完成退出去,main执行完成再退出去,栈清空 方法的运行区域:栈内存 方法内部的变量:栈内存 */ public class Test4 { public static void main(String[] args) { // 目标:理解方法的内存运行机制 study(); } public static void eat(){ System.out.println("吃饭~"); } public static void sleep(){ System.out.println("睡觉~"); } public static void study(){ eat(); System.out.println("学习~"); sleep(); } }
18:方法参数传递之——基本类型的参数传递【值传递】
package com.itheima.param; /** 基本类型的参数传递:int,double等 理解Java的基本类型的参数传递:值传递。 值传递:形参 a 传递 给c,传递的是 a的值,而不是传递 a本身,方法内部无论对c做什么改变不会影响a的值 把自己的值拷贝一份给别人,自己的不会变化的 形参:以方法为例,就是方法定义时的变量。 实参:在方法内部定义的变量 值传递,传输的是实参存储的值 同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法 */ public class MethodDemo1 { public static void main(String[] args) { int a = 10; change(a); System.out.println(a); // 10 } public static void change(int a){ System.out.println(a); // 10 a = 20; // 修改的是 change 方法 内部的 a,a的值肯定是20,不影响外面的 System.out.println(a); // 20 } }
package com.itheima.param; /** 目标:理解引用类型的参数传递机制:值传递,区分其不同点 引用类型的参数传递:数组 传递变量里存储的地址 基本类型和引用类型的参数在传递的时候有什么不同?: 都是值传递 基本类型的参数传输存储的数据值 引用类型的参数传输存储的地址值 */ public class MethodDemo2 { public static void main(String[] args) { // 黄波 人生导师!! 拓展培训! int[] arrs = {10, 20, 30}; change(arrs); System.out.println(arrs[1]); // 222 } public static void change(int[] arrs){ System.out.println(arrs[1]); // 20 arrs[1] = 222; System.out.println(arrs[1]); // 222 } }
package com.itheima.param; /* 需求:定义方法,可以打印任意整型数组的内容:[12, 32, 23] 1、定义一个方法:参数:整型数组类型的变量 返回值类型申明:void 需求分析: 定义一个方法,要求该方法能够接收数组,并输出数组内容。 ---> 需要参数吗?需要返回值类型申明吗 不需要,打印就行,不需要声明返回值类型 定义一个静态初始化的数组,调用该方法,并传入该数组 */ public class MethodTest3 { public static void main(String[] args) { // 4、定义数组,再调用方法 int[] arr = {12, 32, 23}; printArray(arr); System.out.println("-----------------"); int[] arr2 = {}; printArray(arr2); System.out.println("-----------------"); int[] arr3 = null; printArray(arr3); } public static void printArray(int[] arr){ if(arr != null){ // 2、把数组内容打印出来。 System.out.print("["); // 3、开始遍历数组中的每个数据 for (int i = 0; i < arr.length; i++) { // 如果发现是最后一个元素不加逗号 // if(i == arr.length - 1){ // System.out.print(arr[i]); // }else { // System.out.print(arr[i] + ", "); // } System.out.print(i == arr.length - 1 ? arr[i] : arr[i] + ", "); // 三元运算符 问是否到了最后一个元素,是返回前面的,不是返回后面的 } System.out.println("]"); }else { System.out.println("当前数组对象不存在,其地址是:null"); } } }
package com.itheima.param; /** 需求:从整型数组中查询某个数据的索引返回,不存在该数据返回-1 需求分析: 1:是否需要返回值类型?是否需要参数申明 2:定义数组,并指定要搜索的元素值,调用方法得到返回的结果输出即可。 */ public class MethodTest4 { public static void main(String[] args) { int[] arr = {11, 22, 33, 66, 87, 19}; // 3、定义数组,调用方法 int index = searchIndex(arr, 17); System.out.println("您查询的数据的索引是:" + index); } public static int searchIndex(int[] arr, int data){ // 1、定义一个方法:参数接收数组,要查询的数据,返回值:整型 for (int i = 0; i < arr.length; i++) { // 2、开始找出这个数据的索引 if(arr[i] == data){ return i; } } return -1; // 查无此元素! } }
package com.itheima.param; /** 需求:比较任意2个整型数组的内容是否一样,一样返回true 反之 如果两个数组的类型,元素个数,元素顺序和内容是一样的我们就认为这2个数组是一模一样的。 分析: 1、定义方法: 是否需要返回值类型?是否需要申明参数? 2、在方法内部完成判断的逻辑,并返回布尔结果 */ public class MethodTest5 { public static void main(String[] args) { int[] arr1 = {10, 20, 30}; int[] arr2 = {10, 20, 30}; System.out.println(compare(arr1, arr2)); System.out.println("-------------------"); int[] arr3 = null; int[] arr4 = {}; System.out.println(compare(arr3, arr4)); } public static boolean compare(int[] arr1, int[] arr2){ // 1、定义一个方法:参数:接收2个整型数组,返回值类型:布尔类型 if(arr1 != null && arr2 != null){ // 两个数组都不为 null if(arr1.length == arr2.length){ // 2、判断2个数组的内容是一样的呢 for (int i = 0; i < arr1.length; i++) { if(arr1[i] != arr2[i]){ // 一个位置不相等 就返回 false return false; } } return true; // 是一样的!数据循环比完了还没返回 false那么就是True,值都一样 }else { return false; } }else { return false; } } }
19:方法参数传递之——引用类型的参数传递【地址传递】
基本类型和引用类型的参数在传递的时候有什么不同?
都是值传递。
基本类型的参数传输存储的数据值。
引用类型的参数传输存储的地址值。
20:方法重载 ——>同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法
方法重载的识别技巧:
只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管!(如:修饰符,返回值类型都无所谓)
形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称
package com.itheima.overload; /* 目标:识别方法重载的形式。并理解其调用流程,最后需要知道使用方法重载的好处。 同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法 重载的方法调用的时候是不会冲突的,调用方法的时候会根据方法的参数不同来区分具体那个方法 方法重载的作用: 可读性好,方法名称相同提示是同一类型的功能,通过形参不同实现功能差异化的选择,这是一种专业的代码设计。 */ public class MethodDemo1 { public static void main(String[] args) { fire(); // 没有带参数找的是第一个 fire("岛国"); // 一个字符串参数找的 第二个 fire("岛国", 1000); // 找第三个 } public static void fire(){ fire("米国"); } public static void fire(String location){ fire(location, 1); } public static void fire(String location, int number){ System.out.println("默认发射"+number+"枚武器给"+location+"~~~"); } }
package com.itheima.overload; /** 方法重载的识别技巧 只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管!(如:修饰符,返回值类型都无所谓) 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称 */ public class MethodDemo2 { public static void open() {} // 新方法,第一个方法不会重载 public static void open(int a) {} // 重载方法 static void open(int a, int b) {} // 重载方法 public static void open(double a, int b) {} // 重载方法 public static void open(int a, double b) {} // 重载方法 // public void open(int i, double d) { } // 重复方法,非重载方法 public static void OPEN(){ } // 新方法,名称不同 }
21:return 关键字的重点使用
package com.itheima.returndemo; /** 目标:明确return关键字的作用。 return; ---> 可以立即跳出并结束当前方法的执行,可以使用再任何方法中,方法没有返回值也可以使用 如果要直接结束当前方法的执行,怎么解决? return; 跳出并立即结束所在方法的执行。 break; 跳出并结束当前所在循环的执行。 continue; 结束当前所在循环的当次继续,进入下一次执行。 */ public class ReturnDemo { public static void main(String[] args) { System.out.println("main开始。。"); chu(10 , 0); System.out.println("main结束。。"); } public static void chu(int a, int b){ if(b == 0){ System.out.println("您输入的数据有问题,除数不能是0!!"); return; // 立即跳出当前方法,并结束当前方法的执行。 除数等于 0的时候立即结束方法,不容易出Bug } int c = a / b; System.out.println("结果是:" + c); } }
22:编程案例演练
package com.itheima; import java.util.Scanner; /** 需求:机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。 按照如下规则计算机票价格: 旺季(5-10月)头等舱9折,经济舱8.5折, 淡季(11月到来年4月)头等舱7折,经济舱6.5折。 遇到判断值匹配的时选择什么结构实现? 使用switch分支结构实现 遇到判断区间范围的时候选择什么结构实现? 使用if分支结构实现 */ public class Test1 { public static void main(String[] args) { // 3、录入购买信息,调用方法得到最终结果 Scanner sc = new Scanner(System.in); System.out.println("机票原价:"); double price = sc.nextDouble(); System.out.println("月份:"); int month = sc.nextInt(); System.out.println("仓位类型(头等舱、经济舱):"); String type = sc.next(); double rs = calc(price, month, type); System.out.println("您当前购买机票的价格是:" + rs); } public static double calc(double money, int month, String type){ // 1、定义一个方法:形参(原价、月份、头等舱经济舱) 返回值类型申明:double if(month >= 5 && month <= 10){ // 2、判断月份是淡季还是旺季 并且 5到10月旺季 switch (type){ // 头等舱,经济舱 单值匹配使用 switch case "经济舱": money *= 0.85; break; case "头等舱": money *= 0.9; break; default: // 其他情况 System.out.println("您输入的仓位不正确~~"); money = -1; // 当前无法计算价格了!返回 -1 } }else if(month == 11 || month == 12 || month >= 1 && month <= 4){ // 淡季 ||或 &&且 switch (type){ case "经济舱": money *= 0.65; break; case "头等舱": money *= 0.7; break; default: System.out.println("您输入的仓位不正确~~"); money = -1; // 当前无法计算价格了! } }else { System.out.println("月份有问题"); money = -1; // 价格也有问题 } return money; } }
package com.itheima; /** 需求:找出101-200之间的素数输出: 素数是什么:如果除了1和它本身以外,不能被其他正整数整除,就叫素数。 分析: 101-200之间的数据可以采用循环依次拿到; 每拿到一个数,判断该数是否是素数。 判断规则是:从2开始遍历到该数的一半的数据,看是否有数据可以整除它,有则不是素数,没有则是素数。 如果最终判定是素数,即可输出展示。 比如能整除 10 的数一点在 2 和5之间,其实是10开平方 */ public class Test2 { public static void main(String[] args) { for (int i = 101; i <= 200 ; i++) { // 1、定义一个循环,找到101-200之间的全部数据 boolean flag = true; // 信号位:标记 // 一开始认为当前数据是素数。 for (int j = 2; j < i / 2; j++) { // 2、判断当前遍历的这个数据是否是素数 if(i % j == 0){ flag = false; // 假设失败了,i不是素数 break; // 没有必要继续判定下去了! } } if(flag){ // 3、根据判定的结果选择是否输出这个数据,是素数则输出 System.out.print(i + "\t"); } } } }
package com.itheima; import java.util.Random; /** 需求:定义方法实现随机产生一个5位的验证码,每位可能是数字、大写字母、小写字母 定义一个方法返回一个随机验证码:是否需要返回值类型申明?String 是否需要申明形参:int n,需要声名几位验证码参数 分析: 定义一个方法,生成验证码返回:返回值类型是String,需要形参接收位数。 在方法内部使用for循环依次生成每位随机字符,并连接起来。 把连接好的随机字符作为一组验证码返回 */ public class Test3 { public static void main(String[] args) { String code = createCode(8); // 4、调用获取验证码的方法得到一个随机的验证码 System.out.println("随机验证码:" + code); } public static String createCode(int n){ // 1、定义一个方法返回一个随机验证码:需要返回值类型申明?String 需要申明形参:int n String code = ""; // 3、定义一个字符串变量记录生成的随机字符 Random r = new Random(); // 随机数模块 for (int i = 0; i < n; i++) { // 2、定义一个for循环,循环n次,依次生成随机字符 int type = r.nextInt(3); // 随机:0 1 2 // 3、生成一个随机字符:英文大写 小写 数字 (0 1 2) switch (type){ case 0: char ch = (char) (r.nextInt(26) + 65); // 大写字符(A 65 - Z 65+25) (0 - 25) + 65 字符char,强转(char) alt+回车选中第一个 code += ch; break; case 1: // 小写字符(a 97 - z 97+25) (0 - 25) + 97 char ch1 = (char) (r.nextInt(26) + 97); code += ch1; break; case 2: // 数字字符 code += r.nextInt(10); // 0 - 9 break; } } return code; } }
package com.itheima; /** 需求:把一个数组中的元素复制到另一个新数组中去 分析: 需要动态初始化一个数组,长度与原数组一样。 遍历原数组的每个元素,依次赋值给新数组。 输出两个数组的内容 数组的拷贝是什么意思? 需要创建新数组,把原来数组的元素赋值过来 */ public class Test4 { public static void main(String[] args) { int[] arr1 = {11, 22, 33, 44}; // int[] arr2 = arr1; // 没有完成了数组复制,这样只是地址赋值,内存中数组对象只有一个 int[] arr2 = new int[arr1.length]; // new创建一个新的数组arr2,长度和 arr1相同,然后遍历 arr1内容往 arr2里拷贝 copy(arr1 , arr2); // arr1 的元素拷贝到 arr2 里面去 printArray(arr1); printArray(arr2); } public static void printArray(int[] arr){ // 打印数组内容 System.out.print("["); for (int i = 0; i < arr.length; i++) { System.out.print(i == arr.length - 1 ? arr[i] : arr[i] + ", "); } System.out.println("]"); } public static void copy(int[] arr1, int[] arr2){ // 正式完成元素的复制 for (int i = 0; i < arr1.length; i++) { arr2[i] = arr1[i]; } } }
package com.itheima; import java.util.Scanner; /** 需求:在唱歌比赛中,有6名评委给选手打分,分数范围是[0 - 100]之间的整数。 选手的最后得分为:去掉最高分、最低分后的4个评委的平均分,请完成上述过程并计算出选手的得分 使用动态初始化数组,因为一开始不确定分数,确定容器再录入分数 分析: 把6个评委的分数录入到程序中去 ----> 使用数组 遍历数组中每个数据,进行累加求和,并找出最高分、最低分。 按照分数的计算规则算出平均分 如何实现评委打分案例 定义一个动态初始化的数组用于存储分数数据。 定义三个变量用于保存最大值、最小值和总和。 遍历数组中的每个元素,依次进行统计。 遍历结束后按照规则计算出结果即可 */ public class Test5 { public static void main(String[] args) { int[] scores = new int[6]; // 1、定义一个动态初始化的数组,用于后期录入6个评委的分数 Scanner sc = new Scanner(System.in); // 2、录入6个评委的分数 for (int i = 0; i < scores.length; i++) { System.out.println("请您输入第" + (i + 1) +"个评委的打分:"); int score = sc.nextInt(); scores[i] = score; // 3、把这个分数存入到数组的对应位置处 } // int max = scores[0] , min = scores[0] , sum = 0; // 3、遍历数组中的每个数据,找出最大值 最小值 总分 int max = scores[0] ; // 最大值,第一个分数作为参照物 int min = scores[0] ; // 最小值 int sum = 0; // 总分 for (int i = 0; i < scores.length; i++) { if(scores[i] > max){ max = scores[i]; // 替换最大值变量存储的数据 } if(scores[i] < min){ min = scores[i]; // 替换最小值变量存储的数据 } sum += scores[i]; // 统计总分 } System.out.println("最高分是:" + max); System.out.println("最低分是:" + min); double result = (sum - max - min) * 1.0 / (scores.length - 2); // 4、统计平均分即可 * 1.0得到一个准确的小数 System.out.println("选手最终得分是:" + result); } }
package com.itheima; /** 需求:某系统的数字密码,比如1983,采用加密方式进行传输,规则如下:先得到每位数, 然后每位数都加上5再对10求余,最后将所有数字反转,得到一串新数。 分析 将每位数据存入到数组中去,遍历数组每位数据按照规则进行更改,把更改后的数据从新存入到数组中。 将数组的前后元素进行交换,数组中的最终元素就是加密后的结果。 本次案例中是如何完成数组元素的反转的 定义2个变量分别占数组的首尾位置 一个变量往前走,一个变量往后走,同步交换双方位置处的值 */ public class Test6 { public static void main(String[] args) { int[] arr = new int[]{8, 3, 4, 6}; // 1、定义一个数组存储需要加密的数据 {8, 3, 4, 6} {1, 9, 8, 3} for (int i = 0; i < arr.length; i++) { // 2、遍历数组中的每个数据,按照规则进行修改 arr[i] = (arr[i] + 5) % 10; } // 3、把数组中的元素进行反转操作。 for (int i = 0, j = arr.length - 1; i < j; i++, j--) { // 交换 i 和 j位置处的值,即可反转 int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; } // 4、遍历数组中的每个元素输出即可 for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); } } }
package com.itheima; import java.util.Random; import java.util.Scanner; /** 需求:一个大V直播抽奖,奖品是现金红包,分别有{2, 588 , 888, 1000, 10000}五个奖金。 请使用代码模拟抽奖,打印出每个奖项,奖项的出现顺序要随机且不重复。打印效果如下:(随机顺序,不一定是下面的顺序) */ public class Test7 { public static void main(String[] args) { // 1、定义一个数组存储可以抽奖的金额 总数 int[] money = {2, 588, 888, 1000, 10000}; // 2、定义一个数组用于存储已经被抽中的奖金金额。 int[] lockMoney = new int[money.length]; // 3、开始模拟抽奖逻辑 Scanner sc = new Scanner(System.in); Random r = new Random(); for (int i = 0; i < money.length; i++) { // 分别代表抽奖一次。 System.out.println("您要开始打开红包吗,您可以输入任意内容进行抽奖:"); sc.next(); // 目的是为了让程序在这里等一下,直到用户按了数据和回车就下来抽奖一次! while (true) { // 4、开始抽奖了,随机一个索引取提取金额 int index = r.nextInt(money.length); int currentMoney = money[index]; boolean flag = true; // 代表默认没有被抽过 // 5、判断这个红包金额之前是否有人抽中过! for (int j = 0; j < lockMoney.length; j++) { if(lockMoney[j] == currentMoney){ // 说明这个金额已经被抽过了! flag = false; // 表示已经被抽走了 break; } } if(flag){ System.out.println("您当前很幸运,抽中了:" + currentMoney); // 必须把这个金额放到被抽中的数组中去 lockMoney[i] = currentMoney; break; // 当次抽象已经结束! } } } } }
package com.itheima; import java.util.Random; import java.util.Scanner; /** 需求:双色球模拟 随机6个红球号码(1-33,不能重复),随机一个蓝球号码(1-16),可以采用数组装起来作为中奖号码 本次案例中是如何去统计红球的命中数量的? 遍历用户的每个选号,然后遍历中奖号码的数组。 看当前选号是否在中奖号码中存在,存在则命中数量加1 */ public class Test8 { public static void main(String[] args) { int[] luckNumbers = createLuckNumber(); // 1、随机6个红球号码(1-33,不能重复),随机一个蓝球号码(1-16),可以采用数组装起来作为中奖号码 // printArray(luckNumbers); int[] userNumbers = userInputNumbers(); // 2、录入用户选中的号码 judge(luckNumbers, userNumbers); // 3、判断中奖情况 } public static void judge(int[] luckNumbers, int[] userNumbers ){ // 判断是否中奖了。 // luckNumbers = [12, 23, 8, 16, 15, 32, 9] // 特例思维:先举个例子分析 // userNumbers = [23, 13, 18, 6, 8, 33, 10] // 1、定义2个变量分别存储红球命中的个数,以及蓝球命中的个数。 拿到红球中了几个,篮球中了几个 判断中奖情况 int redHitNumbers = 0; int blueHitNumbers = 0; // 2、判断红球命中了几个,开始统计 遍历用户数组,去中奖前6个元素进行匹配,找到就是命中 for (int i = 0; i < userNumbers.length - 1; i++) { // 嵌套循环 先遍历用户的数组,然后遍历对比中奖号码 for (int j = 0; j < luckNumbers.length - 1; j++) { // 每次找到了相等了,意味着当前号码命中了 if(userNumbers[i] == luckNumbers[j]){ redHitNumbers ++ ; // 红球数量 ++ 并且种族for循环 break; } } } blueHitNumbers = luckNumbers[6] == userNumbers[6] ? 1 : 0; // 蓝球号码是否命中了,三元运算符 System.out.println("中奖号码是:" ); printArray(luckNumbers); System.out.println("您投注号码是:" ); printArray(userNumbers); System.out.println("您命中了几个红球:" + redHitNumbers); System.out.println("您是否命中蓝球:" + ( blueHitNumbers == 1 ? "是": "否" ) ); // 判断中奖情况了 if(blueHitNumbers == 1 && redHitNumbers < 3){ // 并且 System.out.println("恭喜您,中了5元小奖!"); }else if(blueHitNumbers == 1 && redHitNumbers == 3 || blueHitNumbers == 0 && redHitNumbers == 4){ System.out.println("恭喜您,中了10元小奖!"); }else if(blueHitNumbers == 1 && redHitNumbers == 4 || blueHitNumbers == 0 && redHitNumbers == 5){ System.out.println("恭喜您,中了200元!"); }else if(blueHitNumbers == 1 && redHitNumbers == 5){ System.out.println("恭喜您,中了3000元大奖!"); }else if(blueHitNumbers == 0 && redHitNumbers == 6){ System.out.println("恭喜您,中了500万超级大奖!"); }else if(blueHitNumbers == 1 && redHitNumbers == 6){ System.out.println("恭喜您,中了1000万巨奖!可以开始享受人生,诗和远方!!"); }else { System.out.println("感谢您为福利事业做出的突出贡献!!"); } } public static int[] userInputNumbers(){ int[] numbers = new int[7]; // a、动态初始化一个数组,长度为7 Scanner sc = new Scanner(System.in); for (int i = 0; i < numbers.length - 1; i++) { System.out.println("请您输入第"+(i + 1)+"个红球号码(1-33、不重复):"); int data = sc.nextInt(); numbers[i] = data; } System.out.println("请您输入一个蓝球号码(1-16):"); // b、录入一个蓝球号码 int data = sc.nextInt(); numbers[numbers.length - 1] = data; return numbers; // 返回数组对象的地址 } public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } public static int[] createLuckNumber(){ int[] numbers = new int[7]; // [12, 23, 0, 0, 0, 0, | 0] // a、定义一个动态初始化的数组,存储7个数字 // i // b、遍历数组,为每个位置生成对应的号码。(注意:遍历前6个位置,生成6个不重复的红球号码,范围是1-33) Random r = new Random(); for (int i = 0; i < numbers.length - 1; i++) { // 为当前位置找出一个不重复的1-33之间的数字 while (true) { int data = r.nextInt(33) + 1; // 1-33 ====> (0-32) + 1 // c、注意:必须判断当前随机的这个号码之前是否出现过,出现过要重新随机一个,直到不重复为止,才可以存入数组中去。 boolean flag = true; // 定义一个flag变量,默认认为data是没有重复的 for (int j = 0; j < i; j++) { if(numbers[j] == data) { // 等于,说明 data当前这个数据之前出现过,不能用, flag = false; // 出现过,flag改成 false,循环没必要跑了 break; } } if(flag) { // flag for 循环后还是true,说明数据找遍了没有相等的,说明data可用,data这个数据之前没有出现过 numbers[i] = data; break; // 数据插入了那么结束 while循环, } } } numbers[numbers.length - 1] = r.nextInt(16) + 1; // d、为第7个位置生成一个1-16的号码作为蓝球号码 return numbers; } }
分类:
JAVA篇
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!