目录
1. 方法的基本用法
1.1 方法的定义
方法是一段实现某功能的可以进行重复使用的代码片段,类似于C语言的函数;
1.2 方法定义语法
public stactic 方法返回值 方法名称([形式参数列表]){
函数体(方法体)
return [返回值];
}
//函数名称采用小驼峰命名
注:没有返回值的方法不能定义变量来接收,也不能进行进行打印;
1.3 方法调用的执行过程
(1)求和函数调用执行过程:
(2)求阶乘和函数的调用执行过程:
public static void main(String[] args) {
//求1!+2!+3!+4!+5!
int sum=0;
for(int i=1;i<=5;i++){
//调用fac函数求i的阶乘并累加
sum+=fac(i);
}
System.out.println("sum = "+sum);
}
//定义函数fac求某个数的阶乘
public static int fac(int n){
int ret=1;
for(int i=1;i<=n;i++){
ret*=i;
}
return ret;
}
输出结果为:
1.4 实参和形参的关系
以交换两个整型变量的值为例:
运行以下代码:
public static void main(String[] args) {
int a=10,b=20;
System.out.println("a = 10, b = 20");
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;
}
输出结果为:
并没有实现两个变量数值的交换;
在java中,不能通过取地址得到栈上的地址,此处不能像C语言一样通过传址调用进行交换变量的值,可以采用传引用类型参数的方法来实现该功能,此处以数组解法为例:
public static void main(String[] args) {
//swap two variable
System.out.println("a = 10, b = 20");
int[] arr={10,20};
swap(arr);
System.out.println("a = "+arr[0]+", b = "+arr[1]);
}
public static void swap(int[] arr){
int tmp=arr[0];
arr[0]=arr[1];
arr[1]=tmp;
}
输出结果为:
2.方法的重载
2.1 重载的应用场景
试编写函数实现int 和 double 两种数据类型变量的求和:
代码1:如果只写一个返回类型为int的add函数:
public static void main(String[] args) {
//求 int double类型的两个变量的和
System.out.println("10 + 20 = "+add(10,20));
System.out.println("10.5 + 20.5 = "+addd(10.5,20.5));
}
public static int add(int a,int b){
return a+b;
}
报错如下:
代码2:如果写两个函数分别实现int 和double类型的两个变量的求和功能:
public static void main(String[] args) {
//求 int double类型的两个变量的和
System.out.println("10 + 20 = "+addi(10,20));
System.out.println("10.5 + 20.5 = "+addd(10.5,20.5));
}
public static int addi(int a,int b){
return a+b;
}
public static double addd(double a,double b){
return a+b;
}
运行结果如下:
以上两种方法一个类型匹配错误,一个还需重新命名功能相同的方法,针对以上问题java中允许方法重载,有效地解决了这个问题:
2.2 方法重载的使用
public static void main(String[] args) {
System.out.println("10+20="+add(10,20));
System.out.println("10.5+20.5="+add(10.5,20.5));
System.out.println("10.3+10.3+10.3="+add(10.3,10.6,20.5));
}
//两个int类型变量求和
public static int add(int x,int y){
return x+y;
}
//两个double类型变量求和
public static double add(double x,double y){
return x+y;
}
//三个double类型变量求和
public static double add(double x, double y,double z){
return x+y+z;
}
输出结果为:
2.3 重载的规则
(1)方法名相同;
(2)方法的参数列表(形参数目、类型等);
(3)方法的返回值不同不构成重载:
public static int mul(int x,int y){
return x*y;
}
public static double mul(int x,int y){
return (double)(x*y);
}
如上文代码所示:两个函数函数名相同、参数列表相同但返回值不同时,不构成重载;
3. 方法递归
一个方法在执行过程中调用自身就是递归:
递归与数学归纳法类似,初始条件与递推公式构成递归;
递归需要两个前提:① 初始条件或称递归趋近终止的条件;② 函数调用自身;
示例1:使用递归实现n的阶乘:
public static void main(String[] args) {
int ret=fac(5);
System.out.println(ret);
}
public static int fac(int n){
if(n==1){
return 1;
}
return n * fac(n-1);
}
输出结果为:
示例2:斐波那契数列:
public static void main(String[] args) {
//斐波那契
System.out.println(fib1(45));
System.out.println(fib2(45));
}
public static int fib2(int n){
//循环或迭代法
if(n==1||n==2){
return 1;
}
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;
}
public static int fib1(int n){
//递归法
if(n==1||n==2){
return 1;
}
else{
return fib1(n-1)+fib1(n-2);
}
}
输出结果为:
注:对于斐波那契数列来说,使用递归法的重复运算非常庞大,故而使用非递归的循环或称迭代法计算效率会得到提升;
示例3:递归求1+2+3+...+n:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Please input n: ");
int n= scanner.nextInt();
System.out.println("sum = "+sumAdd(n));
}
public static int sunAdd(int n){
if(n==1){
return 1;
}
return n+sumAdd(n-1);
}
输出结果为:
示例4:顺序打印一个数字的每一位:
public static void main(String[] args) {
//顺序打印一个数字的每一位
eachNum(1234567);
}
public static void eachNum(int n){
if(n<10){
System.out.print(n%10+" ");
}
else{
eachNum(n/10);
System.out.print(n%10+" ");
}
}
输出结果为:
示例5:使用递归法输入一个非负整数,返回组成它的数字之和:
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
System.out.print("Please input a number: ");
int n=scanner.nextInt();
System.out.println(sumEachNum(n));
}
public static int sumEachNum(int n){
if(n<10){
return n;
}
else {
return sumEachNum(n/10)+n%10;
}
}
输出结果为:
示例6:青蛙跳台阶问题:
一只青蛙一次可以跳上一级台阶,也可以跳上两级,求该青蛙跳上一个n级台阶共有多少种跳法;
public static void main(String[] args) {
//青蛙跳台阶
Scanner scanner = new Scanner(System.in);
System.out.print("Please input a number: ");
int n=scanner.nextInt();
System.out.println(frogJump2(n));
System.out.println(frogJump1(n));
}
public static int frogJump2(int n){
//循环或迭代算法:
if(n==1||n==2){
return n;
}
int f1=1;
int f2=2;
int f3=0;
for(int i=3;i<=n;i++){
f3=f1+f2;
f1=f2;
f2=f3;
}
return f3;
}
public static int frogJump1(int n){
//递归算法
if(n==1||n==2){
return n;
}
else {
return frogJump1(n-1)+frogJump1(n-2);
}
}
输出结果:
4. 方法示例:
示例1:打印某范围之间的独身数、水仙花数、四叶玫瑰数、五角星数、六合数:
代码如下:
public static void main(String[] args) {
//输出0~999999之间的独身数、水仙花数、四叶玫瑰数、五角星数、六合数
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();//999999
findNum(n);
}
public static void findNum(int n){
for(int i=0;i<n;i++){
int count=0;
int tmp=i;//防止除10法求数字位数导致i变为0无法对每位数字进行提取
while(tmp!=0){
count++;
tmp=tmp/10;
}
//此时count为该数的位数
tmp=i;
int sum=0;
while(tmp!=0){
sum+=Math.pow(tmp%10,count); //每一位数字的位数次方
//此处需也为+=模式,因为pow的返回值是一个double类型数据
tmp/=10;
}
if(sum==i){
System.out.println(i);
}
}
}
输出结果为:
示例2:写一个函数返回参数二进制序列中1的个数:
方法一:
代码如下:
public static void main(String[] args) {
//返回参数二进制中1的个数
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int ret = count1(num);
System.out.println(ret);
}
public static int count1(int n){
int count=0;
while(n!=0){
if((n&1)==1){
count++;
}
n=n>>>1;
}
return count;
}
输出结果为:
方法二:
代码如下:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num=scanner.nextInt();
int ret=count1_(num);
System.out.println(ret);
}
public static int count1_(int n){
int count=0;
while(n!=0){
count++;
n=n&(n-1);
}
return count;
}
输出结果为:
示例3:获取一个数二进制序列中所有偶数位和奇数位,分别输出二进制序列:
(奇数位偶数位取决于初始位置定位)
public static void main(String[] args) {
oddSite(11);
System.out.println("\n");
evenSite(11);
}
public static void oddSite(int n){
for(int i=30;i>=0;i-=2){
System.out.print(((n>>i)&1)+" ");
}
}
public static void evenSite(int n){
for(int i=31;i>=1;i-=2){
System.out.print(((n>>i)&1)+" ");
}
}
输出结果为: