函数(Function)
什么是函数?
函数就是具有名称的特定功能代码的集合,也叫做方法。
为什么使用函数?
- 封装常用的代码
- 提高程序代码的复用性
- 让代码看起来更加的简洁
Java 中如何定义函数
下面举例一个简单的函数进行分析:
public static int test(int a, int b) {
int c = a + b;
return c;
}
访问修饰符 [static] 返回值类型 方法名([参数类型...]) {
//代码块
[return 返回值]
}
函数调用
当函数被创建之后,无法自己执行,需要我们调用来执行。
如下所示:
public class Demo01 {
public static void main(String[] args) {
int test = add(1, 2);
System.out.println(test);
}
public static int add(int a, int b) {
int c = a + b;
return c;
}
}
因为是静态方法,因此我们不需要创建对应的对象就可以直接在 main 方法中调用它,并返回结果。
函数的分类
- 函数是否存在参数
- 有参函数
- 无参函数
- 函数是否需要返回计算结果
- 无返回值
- 有返回值
局部变量
定义在函数内部的变量,叫做局部变量,局部变量的作用域只在当前函数中有效。
在 Java 中没有全局变量,main 函数中的变量也是局部变量,只是比较特殊,作用域还是 main 函数本身,但是生命周期比较长
函数调用的本质
函数本质是一个对象,存储在堆中
函数本质存储在堆中,当调用时,会临时的压入栈中(push),等调用完成之后,会立即弹出栈(pop),所以函数调用就是瞬时操作。
由于我还是不太清楚函数中栈调用的具体流程图,所以先空着,希望以后知道了再来补充。
函数重载(override)
函数名称相同,但是参数的个数或类型不同,从而在调用的时候,可以通过传参确定要调用的函数。
在重载的方法中,参数列表(参数的个数或类型)必须修改,返回值类型,可以修改(也就是可以修改也可以不修改)。
可以看到当我们只对 add 方法的返回值类型修改时,IDEA 就会提示代码爆红,因为这并不符合重载的规范。
public static int add(int a, int b, int c) {
int d = a + b + c;
return d;
}
这才是正确的重载规范。
重载本质是对功能的扩展,而不是代码的复用!!!
函数的递归
递归:函数自身调用自身
如果要使用递归:必须要有终止条件,没有终止条件的递归就是一个死循环!!!
递归的优点在于,相比非递归函数,递归函数代码更加简洁清晰,可读性更好。
缺点:由于调用递归函数需要多次用到系统栈内存,所以空间消耗要比非递归代码要大很多。而且,由于递归深度太大,或者由于函数本身逻辑错误,可能会导致内存溢出,系统崩溃。🙃
求第n项的斐波那契数列的值
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
public static int test(int n) {
if(n == 0) {
return 0;
}
if(n == 1 || n == 2) {
return 1;
}else {
return test(n-1) + test(n - 2);
}
}
不死兔问题
小明今年高考,考了700,父母,给他买了一对刚刚出生小兔子,
四个月后成长为成年兔子,成年后,每过一个月,假设生出一对新的小兔子
问:第n月,小明家共有多少对兔子。 1 1 1 1 2 3 4 5 7 10 14 a[n] = a[n-1] + a[n - 4]
public class Demo03 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(recursionRabbit(i));
}
}
public static int recursionRabbit(int month) {
if (month <= 4) {
return 1;
} else {
return recursionRabbit(month - 1) + recursionRabbit(month - 4);
}
}
}
楼梯走法问题:
一个人开始上楼梯,假设这个人每一次只能上一个或者两个台阶
当他到达第n个台阶时,问:共有多少种走法?
public static int test(int n) {
if(n == 0) {
return 0;
}
if(n == 1 || n == 2) {
return n;
}else {
return test(n-1) + test(n - 2);
}
}