前面与c都很相似,于是我决定从这一章开始复盘java的学习

一、方法
方法的好处主要体现在使用方便,可以在多处调用,不必反复造轮子
1、方法的使用


这就是一个简单的方法创建:
public class java0517 {
public static int ret(int a, int b){
return a + b;
}
其中int是方法类型,ret是起的方法名字
2、方法的调用
java中没用声明的说法,使用方法的时候直接调用就好:
public static void main1(String[] args) {
int a = 3;
int b = 4;
int c = ret(3, 4);
System.out.println(c);
}
}
代码示例:计算1!+2!+3!+4!+5!
//将计算一个数字的阶乘功能写入方法
public class java0518 {
public static void main(String[] args) {
int a = 10;
int sum = 0;
int i = 0;
for (i = 1; i <= 10; i++) {
sum += num(i);
}
System.out.println(sum);
}
public static int num(int a)
{
int result = 1;
int i = 0;
for (i = 1; i <= a; i++) {
result *= i;
}
return result;
}
}
如果是常规写法的话,心理路程应该是由 求一个数的阶乘>>>求每个数字阶乘的相加
而这里是将求一个数字的阶乘放在方法里,主方法采取加和的手段
3、实参和形参的关系
形参只是方法定义时借助的一个变量,用来保存方法调用时传递过来的值
假如你想对实参的值进行交换:
public class TestMethod {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("交换前: a = " + a + " b = " + b);
swap(a, b);
System.out.println("交换后: a = " + a + " b = " + b);
}
public static void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp
}
}
这样的交换方式其实无法做到交换两个实参的值,因为swap方法调用时只是拷贝了一份实参的值保存到了形参里面,因此对形参x和y操作并无法改变a和b的值
4、java中方法重载的理念
当想要使用方法让两个整数相加时,同时也想实现两个小数相加
我们可能会使用下面的方法:
public class TestMethod {
public static void main(String[] args) {
int a = 10;
int b = 20;
int ret = addInt(a, b);
System.out.println("ret = " + ret);
double a2 = 10.5;
double b2 = 20.5;
double ret2 = addDouble(a2, b2);
System.out.println("ret2 = " + ret2);
}
public static int addInt(int x, int y) {
return x + y;
}
public static double addDouble(double x, double y) {
return x + y;
}
}
但是这样每次遇到不同类型就要新创建一个函数会不会太麻烦了?
于是便有了重载的概念:
在java中如果多个方法的名字相同或者参数列表或者参数类型次序不同,那就称该几种方法被重载了,编译器会挑选最适合的来计算
public class java0518 {
public static void main(String[] args) {
add(10,20);
add(1.2,1.3);
add(1.2,1.3,1.4);
}
public static int add(int x, int y){
return x + y;
}
public static double add(double x, double y){
return x + y;
}
public static double add(double x, double y, double z){
return x + y + z;
}
}
二、递归
递归就是方法自己调用自己的过程,它通常这样组成:
起始条件:相当于结束条件,当N=1就结束了
递推公式:例如求N!用递推公式求就是N*(N-1) (这个步骤通常十分困难)
例一、求数字5的阶乘:
public class java0518 {
public static void main(String[] args) {
int a = 5;
int num = ret(5);
System.out.println(num);
}
public static int ret(int a){
if(a == 1 || a == 0){
return 1;
}else{
return a * ret(a - 1);
}
}
}
这个递归的运行过程是:

在这里的if里的内容就是终止条件
遇到终止条件以后从内层逐步回溯计算结果
可视化流程:
ret(5)
│
└─ 5 * ret(4)
│
└─ 4 * ret(3)
│
└─ 3 * ret(2)
│
└─ 2 * ret(1)
│
└─ 1 ← 终止条件,开始回溯
例二、打印数字的每一位
通过上一题我们可以得到一个结论 : 在一些题目中我们需要一个执行接近终止条件的程序和一个执行算法程序
具体什么意思呢?看下面这个题目:
//递归方法求一个数字每一位之和
public class java0519 {
public static void main(String[] args) {
int a = 1314;
int num = add(1314);
System.out.println(num);
}
public static int add(int a){
if(a < 10){
return a;
}else {
return a % 10 + add(a / 10);
}
}
}
在这个代码里面 add(a / 10)就是接近终止条件的程序
而 a % 10 就是执行算法程序
例三、求斐波那契数的第n项
这个代码使用递归在后台的计算将比较庞大,因为有些地方会被反复计算,而这道题目就不包括上面总结的规律,执行算法程序运行过程中就可以运行到终止条件
//递归求斐波那契数列第n项
public class java0519 {
public static void main(String[] args) {
int a = 4;
int num = ret(4);
System.out.println(num);
}
public static int ret(int a){
if(a == 1 || a== 2){
return 1;
}else{
return ret(a-1) + ret(a - 2);
}
}
}
这里大概逻辑就是,计算ret4时因为不满足终止条件,因此来计算ret3和ret2,ret3又被拆解成了re2和ret1,最后再一步步回溯
因此,迭代在此处才是最优解:
//迭代求斐波那契数第n项
public class java0519 {
public static void main(String[] args) {
int n = 8;
int num = ret(8);
System.out.println(num);
}
public static int ret(int n){
int f1 = 1;
int f2 = 1;
int f3 = 2;
int i = 0;
for(i = 3;i <= n;i++){
if(n == 1 || n == 2){
return 1;
}else{
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
}
return f3;
}
}
这里使用了循环,求第几位数字,程序就执行n-i次(交换n-i次)

完