在 Java 编程里,重载和递归属于非常关键的概念。它们能提升代码的可读性、可维护性以及灵活性。接下来,我们会对这两个概念进行详细阐述。
方法重载
为什么需要方法重载
在编程过程中,我们常常会碰到要实现功能类似但处理数据类型或者参数数量不同的情况。要是为每一种情况都创建一个新的方法名,代码会变得既复杂又难以记忆。方法重载让我们可以运用相同的方法名来处理不同类型或者数量的参数,从而提升代码的可读性和可维护性。
方法重载指的是在同一个类中,存在多个方法拥有相同的方法名,不过参数列表(参数类型、参数个数或者参数顺序)不同。返回值类型和访问修饰符不会影响方法重载。
public static double add(double a,double b){
return a+b;
}
public static int add(int a,int b){
return a+b;
}
public static void main(String[] args) {
int x = 1;
int y = 2;
int ret = add(x,y);
System.out.println(ret);
double a = 1.0;
double b = 2.0;
double reta = add(a,b);
System.out.println(reta);
}
代码解释
在上述代码里,add 方法被重载了两次。第一个 add 方法接收两个 double 类型的参数,返回 double 类型的结果;第二个 add 方法接收两个 int 类型的参数,返回 int 类型的结果。在 main 方法中,依据传入参数的类型,Java 会自动调用对应的 add 方法。
递归
递归的概念
递归是一种编程技巧,在这种技巧里,方法会调用自身。递归方法一般包含两个部分:基本情况(终止条件)和递归情况。基本情况是递归的终止条件,避免无限递归;递归情况则是方法调用自身以解决规模更小的问题。
递归执行过程分析
下面以计算阶乘为例,对递归的执行过程进行分析。
public class RecursionExample {
// 递归计算阶乘
public static int factorial(int n) {
// 基本情况:当 n 为 0 或 1 时,阶乘为 1
if (n == 0 || n == 1) {
return 1;
} else {
// 递归情况:n 的阶乘等于 n 乘以 (n-1) 的阶乘
return n * factorial(n - 1);
}
}
public static void main(String[] args) {
int num = 5;
int result = factorial(num);
System.out.println(num + " 的阶乘是: " + result);
}
}
执行过程分析
当调用 factorial(5) 时,执行过程如下:
factorial(5) 调用 factorial(4),因为 5 不等于 0 或 1,所以返回 5 * factorial(4)。
factorial(4) 调用 factorial(3),返回 4 * factorial(3)。
factorial(3) 调用 factorial(2),返回 3 * factorial(2)。
factorial(2) 调用 factorial(1),返回 2 * factorial(1)。
factorial(1) 满足基本情况,返回 1。
然后依次返回计算结果:
factorial(2) 返回 2 * 1 = 2。
factorial(3) 返回 3 * 2 = 6。
factorial(4) 返回 4 * 6 = 24。
factorial(5) 返回 5 * 24 = 120。
最终,输出结果为 5 的阶乘是 120。
递归能够让代码更加简洁和易于理解,但使用时要留意确保有正确的终止条件,防止出现栈溢出错误。
递归练习
代码示例1 按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)
代码示例2 递归求 1 + 2 + 3 + … + 10
代码示例3 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19
public static void fac(int n){
if(n<10){
System.out.println(n);
return;
}
fac(n/10);
System.out.println(n%10);
}
public static int sum(int n){
if(n==1){
return 1;
}
return n+sum(n-1);
}
public static int NumSum(int n){
if(n/10==0){
return n;
}
return n%10+NumSum(n/10);
}
专项:斐波那契数列
递归:
public static int fib(int n){
if(n==1||n==2){
return 1;
}
return fib(n-1)+fib(n-2);
循环
public static int fib2(int n){
int f1=1;
int f2=1;
int f3=0;
for (int i = 3; i <=n; i++) {
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
return f3;
}
递归方法通过不断调用自身来计算斐波那契数列。其基本思路是,当 n 为 1 或者 2 时,直接返回 1;对于其他的 n 值,返回 fib(n - 1) 与 fib(n - 2) 的和。不过,递归方法存在一个显著的问题,就是会有大量的重复计算。例如,在计算 fib(5) 时,fib(3) 会被多次计算。这导致时间复杂度为 (O(2^n)),在 n 值较大时,性能会变得非常差。所以一般用循环方法