1,回顾
数组的格式:
不知道所有的元素,但是知道要存几个
int [] arr = new int[5];
当我们知道所有元素的时候。
int [] arr = new int[]{1,2,3,4};
推荐简写格式:int [] arr = {1,2,3,4};
获取数组中的元素:
格式:数组名[索引]
获取出来之后,可以赋值给变量再进行计算。
直接输出到控制台上面。
索引:
其实就是一个编号。
可以帮助我们获取数组中的元素,或者帮我们给数组中的元素赋值。
最小索引:0
最大索引:数组的长度-1
索引依次递增,每次+1.
如何给数组中的元素赋值:
格式:数组名[索引] = 值/变量;
表示把右边的数值赋值给左边。
如何获取数组中的长度:
不需要自己去数,length
格式:数组名.length
2,方法的概述
方法是什么?
方法就是把重复的代码进行打包。是语句的集合,它们在一起执行一个功能。
课外拓展 Java都是值传递
格式
public class Demo01 {
//public static修饰符 void返回值类型 main方法
public static void main(String[] args) {
//实际参数 1,2
int sum = add(1,2);
System.out.println(sum);
}
//加法
//形式参数,用来定义
public static int add(int a,int b) {
return a+b;
}
}
void 无返回值类型
修饰符 返回值类型 方法名(参数列表){
…
方法体
…
return 返回值;
}
方法的好处:
提高代码的复用性:
复用性,代码重复使用的特性。
重复的代码都放在方法当中,以后想要用的时候,直接调用就可以了。不需要再次写了,所以提高了代码的复用性。
提高代码的可维护性:
可维护性:当以后要修改重复代码的时候。此时只需要修改方法中的代码就可以了。而且只需要修改一次即可。
方法的特点:
-
需要用到的时候,就直接调用方法。
-
如果不调用方法,方法里面的代码是不会执行的。(不调用,不执行)
方法的重载
1.什么是方法重载
重载就是在一个类中,有相同的函数名称,但形式不同的函数
2.方法的重载规则:
方法名称必须相同。
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
方法的返回类型可以相同也可以不相同。
仅仅返回类型不同不足以成为方法的重载
3.实现理论
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
package Method;
public class Demo02 {
public static void main(String[] args) {
double max = max(10.0,20.0);
System.out.println(max);
}
//比大小
public static double max(double num1, double num2) {
double result = 0;
if( num1 == num2) {
System.out.println("num1 == num2");
return 0 ; //终止方法
}
if(num1 > num2 ) {
result = num1;
}else {
result = num2;
}
return result;
}
//比大小
public static int max(int num1, int num2) {
int result = 0;
if( num1 == num2) {
System.out.println("num1 == num2");
return 0 ; //终止方法
}
if(num1 > num2 ) {
result = num1;
}else {
result = num2;
}
return result;
}
}
20.0
可变参数
package Method;
public class Demo03 {
public static void main(String[] args) {
Demo03 demo03 = new Demo03();
demo03.test(1,2,5,6,75,65,14);
}
public void test( int...i) {
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
System.out.println(i[3]);
System.out.println(i[4]);
System.out.println(i[5]);
System.out.println(i[6]);
}
}
递归(高频问点)
A方法调用B方法
递归就是:A方法调用A方法!就是自己调用自己
利用递归我们可以用简单的程序来解决一些复杂的问题。减少程序代码量
递归结构俩部分:
递归头:什么时候不调用自身方法。如果没有头,就陷入死循环。
递归体:什么时候需要调用自身方法。
package Method;
public class Demo04 {
//递归思想
public static void main(String[] args) {
System.out.println(f(4));
}
//1! 1
//2! 2*1
//5! 5*4*3*2*1 阶乘
//2 2 * f(1)
//3 3 * f(2)
public static int f(int n) {
if (n == 1) {
return 1;
}else {
return n * f(n-1);
}
}
}
计算机
3,方法的第一种格式(无参无返回值)
定义格式:
public static void 方法名(){
//方法体
}
调用格式:
方法名(); //直接调用
注意点:
方法需要先定义,再进行调用,否则会报错。
方法中代码的执行规则:
方法中的代码从上往下依次执行的。
上面的代码没有执行完毕,永远无法执行下面的代码
public class GameMethod2 {
//因为main方法是程序的主入口。
//不管你把main方法定义在哪里,当程序启动之后。
//都会去找main方法,然后从上往下,执行main方法里面的代码。
//只不过,我们习惯性会把main方法写在第一个。
public static void main(String[] args) {
//方法里面的代码。是从上往下依次执行的
System.out.println(111);
method();//表示这行代码一直在执行,永远不会停止
System.out.println(222);
}
public static void method(){
while (true){
}
}
}
问:222 会输出在控制台上吗?
答:不会。因为程序启动之后,会开始从上往下执行main方法中的代码。
首先输出111,然后执行 method();此时就调用了 method方法,执行方法里面的代码。
而方法中是一个死循环,所以方法永远执行不完。222就无法输出到控制台上面。
方法在内存中的运行特点:
一开始的时候,是在方法区的。(临时存储。)
一旦被调用之后,就会进入到栈内存中运行。(执行的时候,才会进栈)
在栈内存中是先进后出。(先进入栈内存的,就后出去。 )
public class Car {
//属性,意味只要有Car的对象就应该有这些属性
//这些属性也叫成员变量,是组成类型的成员
int wheels;
String color;
String brand;
//方法, 格式: 返回值类型 标识符(参数列表...){}
// void 没有返回值
//void driven(String target,int dis) {
// System.out.println("引擎启动"+ target + dis);
// return ;
int driven(String target,int dis) {
// target形式参数
System.out.println("引擎启动"+ target + dis);
return 5 ;
}
}
public class Main {
public static void main(String[] args) {
Car c = new Car();
c.wheels = 5;
Car b = new Car();
b.wheels = 4;
System.out.println(b.wheels);
//"宝鸡" ,4555实际参数
int result = c.driven("宝鸡" ,4555);
System.out.println(result);
}
}
案例:
public class MethodDemo1 {
public static void main(String[] args) {
//定义一个方法,在方法中对一个变量进行奇偶判断
method();
}
//定义一个方法
public static void method(){
int number = 10;
if(number % 2 == 0){
System.out.println("偶数");
}else{
System.out.println("奇数");
}
}
}
4,方法的第二种格式(有参无返回值)
定义格式:
public static void 方法名(数据类型 变量名,数据类型 变量名...){
//方法体;
}
调用格式:
方法名(值);
案例1 - 调用的时候传递常量:
public class MethodDemo2 {
public static void main(String[] args) {
method(5);//一一对应 (数量必须一致,类型也要一致)
}
//带参数方法的定义格式
public static void method(int number){
System.out.println(number);
}
}
案例2 - 调用的时候传递变量:
public class MethodDemo2 {
public static void main(String[] args) {
int a = 10;
method(a);//一一对应 (数量必须一致,类型也要一致)
}
//带参数方法的定义格式
public static void method(int number){
System.out.println(number);
}
}
形参和实参:
形参:全称,形式参数。
方法在定义的时候,写在小括号中的变量。
//定义方法时小括号里面的number就是形参
public static void method(int number){
int a = 10;//这个不是形参。
System.out.println(number);
}
//定义方法时小括号里面的number1和number2就是形参
//在本案例中,有两个形参。
public static void method(int number1,int number2){
...
}
实参:全称,实际参数。
方法在调用的时候,写在小括号中的值。这个值可以是常量,也可以是变量。
public static void main(String [] args){
//调用方法
//在调用的时候,这个数字就是实参。
//他是实际传递给方法的参数。
method(5);
}
//实参 给 形参
//定义方法
public static void method(int number){
...
}
注意点:
形参和实参必须要一一对应。数量要一致,类型也需要保持一致。
案例:
public class MethodDemo3 {
public static void main(String[] args) {
print(5,10);
}
//我哪知道这个方法要不要定义形参。
//我哪知道要定义几个形参
//定义一个方法,打印n ~ m 之间的奇数
public static void print(int n , int m){
for (int i = n; i <= m; i++) {
if(i % 2 != 0){
System.out.println(i);
}
}
}
}
分享定义方法的小技巧:
1,确定这个方法要做什么?
2,方法中做这件事情,需要什么?需要的东西就是形参
5,方法的第三种格式(有参有返回值)
定义格式:
public static 返回值类型 方法名(数据类型 变量名,数据类型 变量名。。。){
方法体;
return 值;
}
调用格式:
-
直接调用
对返回值不做任何处理 — 一般适用于没有返回值的方法
-
赋值调用
把返回值赋值给另外一个变量
-
输出调用
把返回值直接输出到控制台上
案例:
public class MethodDemo6 {
public static void main(String[] args) {
//赋值调用
int result = isSame(10, 20);
System.out.println(result);
//输出调用 --- 将方法的返回值直接输出到控制台上面
System.out.println(isSame(10, 20));
}
//定义一个方法,求出两个数较大值。
//1.确定这个方法要做什么? 求两个数的较大值
//2.我做这件事情,需要什么? 需要两个数
public static int isSame(int a, int b) {
int max = a > b ? a : b ;
return max;
}
}
注意点:
void:表示方法没有任何返回值。
如果方法有返回值,就不能写void了。必须要写实际返回的数据类型。
return:
1,结束方法。
2,把后面的结果,返回给调用处。
6,方法中的参数和返回值如何定义(重点)
技巧:可以有从来确定形参和返回值
1,先确定这个方法能干什么?
2,再确定需要什么才能做这件事情?
需要的东西就是方法的形参
3,方法的返回值在调用处是否需要二次使用。
如果需要二次使用,那么必须要写返回值。
如果不需要二次使用,那么可以写返回值,也可以不写返回值。
案例:
public class MethodDemo8 {
public static void main(String[] args) {
//在调用处,判断两个长方形的周长,比一比谁更长。
int length1 = getLength(10, 5);
int length2 = getLength(20,2);
if(length1 > length2){
System.out.println("第一个长方形长");
}else if(length1 < length2){
System.out.println("第二个长方形长");
}else{
System.out.println("长度相等");
}
}
//定义一个方法,求一个长方形的周长
//如果调用处需要使用到这个结果,那么必须要写返回值。
public static int getLength(int len, int width) {
int length = (len + width) * 2;
return length;
}
}
案例2:
public class MethodDemo9 {
public static void main(String[] args) {
//现在有两个班级。
//每个班级都有3名。
//在本次期中考试的时候,所有的学生都参加了,而且得了一个分数。
//假设分数都是整数的。
//做:比一比,两个班级的平均分谁更高?
//打两个 --- 方法的参数?方法的返回值
//1,我要干嘛?
//2.我需要什么,才能做这件事情?
//3.我做完这件事情之后,调用处,要不要用我的结果。
double avg1 = getAvg(100, 99, 98);
double avg2 = getAvg(95, 97, 100);
if(avg1 > avg2){
System.out.println("第一个班的平均分更高");
}else if(avg1 < avg2){
System.out.println("第二个班的平均分更高");
}else{
System.out.println("两个班级的平均分相等");
}
}
//1,定义一个方法,求班级的平均分
//2, 我要求平均分,我需要知道什么?总分 --- 所有分数相加 --- 你要把所有的分数告诉我
//3,调用处要不要用我的结果?调用处需要使用平均分,因为要比较
public static double getAvg(int score1, int score2, int score3) {
//求总分
int sum = score1 + score2 + score3;
//求平均分
double avg = sum / 3.0;
return avg;
}
}
7,练习:
1,定义一个方法,打印N次"HelloWorld"
public class Test1 {
public static void main(String[] args) {
//定义一个方法,打印N次"HelloWorld"
printHelloWorld(5);//alt + 回车 (快速修正)
}
//注意点:
//1.我要干嘛 --- 决定了方法体
//2.我做这件事情需要什么 --- 决定了形参
//3.调用处是否继续使用当前结果 --- 决定返回值
public static void printHelloWorld(int count) {
for (int i = 0; i < count; i++) {
System.out.println("HelloWorld");
}
}
}
改写:打印次数由键盘录入生成
public class Test1 {
public static void main(String[] args) {
//定义一个方法,打印N次"HelloWorld"
Scanner sc = new Scanner(System.in);
System.out.println("请输入要打印的次数");
int count = sc.nextInt();
printHelloWorld(count);//alt + 回车 (快速修正)
}
//注意点:
//1.我要干嘛 --- 决定了方法体
//2.我做这件事情需要什么 --- 决定了形参
//3.调用处是否继续使用当前结果 --- 决定返回值
public static void printHelloWorld(int count) {
for (int i = 0; i < count; i++) {
System.out.println("HelloWorld");
}
}
}
2,定义一个方法,求数组中所有数字的和
public class Test2 {
public static void main(String[] args) {
//定义一个方法,求数组中所有数字的和
int [] arr1 = {1,2,3,4,5};
getSum1(arr1);
int [] arr2 = {10,20,30};
int sum2 = getSum2(arr2);
System.out.println(sum2);
}
//1,方法要干嘛? 求数组中所有数字的和
//2.我做这件事情,需要什么?需要一个数组
//3,我已经求出了数组的中所有元素的和之后,调用处是否需要继续使用?
//在本题中,并没有说得到结果之后,是否需要继续使用。所以方法可以有返回,也可以没有返回。
public static void getSum1(int [] array) {
//求array数组中所有数字的和
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum = sum + array[i];//+=
}
System.out.println(sum);
}
public static int getSum2(int [] array) {
//求array数组中所有数字的和
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum = sum + array[i];//+=
}
return sum;
}
}
3,定义一个方法,获取一个数组中的最大值
public class Test3 {
public static void main(String[] args) {
//定义一个方法,获取一个数组中的最大值
int [] arr1 = {1,2,3,4,5};
getMax1(arr1);
int [] arr2 = {10,20,30};
int max2 = getMax2(arr2);
System.out.println(max2);
}
//1.我要干嘛?求一个数组中的最大值。
//2.我做这件事情需要什么? 至少得把数组给我。
//3.已经求出最大值了。要不要返回?
//看题目当中,在调用处,要不要继续使用。
//现在本题中,没有说要继续使用,所以这里有也可以,没有也可以。
public static void getMax1(int [] array){
//定义参照物的时候,一定是数组里面的元素。
int max = array[0];
//写循环求最大值
for (int i = 0; i < array.length; i++) {
//array[i] 依次表示数组中的每一个值
if(array[i] > max){
max = array[i];
}
}
//当循环结束之后,max记录的值就是数组中的最大值。
System.out.println(max);
}
public static int getMax2(int [] array){
//定义参照物的时候,一定是数组里面的元素。
int max = array[0];
//写循环求最大值
for (int i = 0; i < array.length; i++) {
//array[i] 依次表示数组中的每一个值
if(array[i] > max){
max = array[i];
}
}
//当循环结束之后,max记录的值就是数组中的最大值。
return max;
}
}
4,定义一个方法,求两个圆的面积和
public class Test4 {
public static void main(String[] args) {
//定义一个方法,求两个圆的面积和
double area1 = getArea(1.5);
double area2 = getArea(2.5);
System.out.println(area1 + area2);//Java中小数计算是有可能不精确的。
}
//1.我要干嘛? 要求一个圆的面积
//2.我在求圆面积,那么需要什么? --- π * 半径 * 半径
//3.求出了面积,要不要把结果告诉调用者?
//是否需要告诉,看调用处是否要继续使用这个结果。 --- 要使用。
public static double getArea(double radii) {
//因为 π 永远不会发生变化。
double area = 3.14 * radii * radii;
return area;
}
}
5,定义一个方法,获取一个随机数,要求:(0~10之间的偶数)
下面的代码是一个错误的示范:
public class Test5 {
public static void main(String[] args) {
//定义一个方法,获取一个随机数,要求:(0~10之间的偶数) -- 0 2 4 6 8 10
int number = getRandomNumber();
System.out.println(number);
}
//1.我要干嘛? 我要求一个 0 ~ 10 范围之内的随机数,而且只能是偶数
//2.我做这件事情需要什么? --- 什么都不需要
//3.结果是否需要返回给调用者? 因为题目中不需要对结果继续使用,所以可以返回,也可以不返回
public static int getRandomNumber(){
Random r = new Random();
//获取一个随机数
int randomNumber = r.nextInt(11);//0 ~ 10
if(randomNumber % 2 == 0){
return randomNumber;
}
//如果仅仅写一个判断,还是不够的。
//如果随机到一个奇数,不会执行到if的语句体。
//那么此时就没有返回值了。
//而方法规定了,一定有一个int类型的返回值,所以语法报错。
}
}
下面的代码是一个正确的示范:
public class Test5 {
public static void main(String[] args) {
//定义一个方法,获取一个随机数,要求:(0~10之间的偶数) -- 0 2 4 6 8 10
int number = getRandomNumber();
System.out.println(number);
}
//1.我要干嘛? 我要求一个 0 ~ 10 范围之内的随机数,而且只能是偶数
//2.我做这件事情需要什么? --- 什么都不需要
//3.结果是否需要返回给调用者? 因为题目中不需要对结果继续使用,所以可以返回,也可以不返回
public static int getRandomNumber(){
Random r = new Random();
//获取一个随机数
//必须要写一个循环,重复生成随机数,如果是奇数,那么重新再生成一次。
//如果是偶数,那么就返回。
while (true) {
int randomNumber = r.nextInt(11);//0 ~ 10
if(randomNumber % 2 == 0){
return randomNumber;
}else{
System.out.println("当前生成的随机数为" + randomNumber + "不符合要求,重新生成一个");
}
}
}
}