本章,让我们来介绍下什么是函数
函数
在java中函数也叫成方法,都是一个意思;函数就是封装了具备特定功能的一段代码块,解决了重复性代码的问题。
为什么需要函数呢?
目的是为了提高程序的复用性和可读性。
函数的格式
|
|
接下来我们在具体说一下里面所包含的一些东西
修饰符:public 公共的、protected受保护的、private也是受保护的 static 静态的;
返回值类型:就是函数所实现的功能结果的数据类型。例如有 int、double 、Boolean;
方法名:也叫函数名,是自己定义,符合标识符命名规则就行;
参数列表:即形式参数列表,用于接收实际参数。
参数类型:参数的数据类型(int、double等等);
参数名:即变量名,也是我们自己定义的。
函数体语句:就是函数要完成的功能,我们所需要具体实现的代码;
return:用来结束函数,每一个函数都有return;如果返回的是void类型,那我们可以省略不写;
返回值:即这个函数的功能的结果 ,由return带回调用地方。
函数的参数传递
形式参数:函数定义时的参数为形式参数------>简称形参
实际参数:函数调用时的参数为实际参数 ------>简称实参
参数传递:只能有实参传给形参
接下来让我们看一段代码
main(){
int a=4;
int b=6;
double c=pow(a,b)
}
pow(a,b){
.....
.....
.....return sum;
}
让我们说一下函数传参的问题
注意:实参和形参在个数、顺序、类型上都要保持一致.
函数传参其实就是实参把常量池的地址赋给形参,请看上图;PS:形参中a,b的改变并不影响实参中的a,b;
调用方法
方法的调用是执行方法中的代码;
根据返回类型的不同有两种调用方法:
如果方法返回一个值 , 对方法的调用通常就当作一个值处理 。 例如 : 1 nt larger= max ( 3 , 4 ) ; 调用方法 max ( 3 , 4 ) 并将其结果賦给变量 larger 。 另一个把它当作值处理的调用例子是 : System . out . println ( max ( B , 4 )) ; 这条语句打印调用方法 max ( 3 , 4 ) 后的返回值 。如果方法返回 void , 对方法的调用必须是一条语句 。 例如 , println 方法返回 void 。 下 面的调用就是一条语句 :System . out . println ( " Weicome to Java ! " ) ;
函数模块化
模块化使得代码易于维护和调试,并且使得代码可以被重用。
使用方法可以减少冗余的代码,提高代码的复用性。方法也可以用来模块化代码,以提高程序的质量。
函数栈运行的流程
让我们插入一段代码看一下,:
public static void main(String[] args){
int a=4;
int b=4;
double c=pow(a,b);
System.out.print(c);
}
public static double pow(double a,int b){
if(b==0){
return 1;
}
double sum=1;
for(int i=1;i<Math.abs(b),i++){
sum+=a;
}
return b>0?sum:1/sum;
}
首先程序先进入主函数当中,先执行主函数当中的代码块;然后系统开辟一片栈空间,然后栈顶指在主函数,然后继续运行主函数当中的代码块,当遇见pow函数时,接下来调用pow函数,然后栈顶就指在pow函数这,先执行pow函数中的代码,然后pow函数执行完以后return,系统把pow函数放出去,栈顶继续指在主函数这,然后主函数return以后,系统把主函数也释放了出去。这种方法叫做先进后出;
函数重载
1.函数的重载指的就是同一个类中出现的同名函数
2.与权限没关系,与返回值类型没关系,与参数名没关系,只有和参数类型的排列组合有关系(注意一下参数类型的向下兼容问题)
3.重载的好处就在于我们可以扩展函数的功能(函数重名,但是参数类型不一样,执行内容也可以不一样)
寻找适当函数的方程
class Test01{
public static void main(String[] args){
int a=3;
int b=4;
System.out.println(add(a,b));
double d=3.14;
double e=5.44;
System.out.println(add(d,e));
System.out.println(add(3,3.14));
System.out.println(add(3.13,9));
}
对两个小数进行加法运算
public static double add(double c,double d){
return c+d;
}
public static String add(String a,String b){
System.out.println("String+String");
return a+b;
}
public static double add(int a,double b){
System.out.println("int+double");
return a+b;
}
public static double add(double a,int b){
System.out.println("double+int");
return a+b;
}
public static double add(double a,double b){
System.out.println("double+double");
return a+b;
}
对两个整数进行加法运算
public static int add(int a,int b){
System.out.println("int+int");
return a+b;
}
}
寻找适当函数的流程
1.看是否有确切的参数定义 int+int 查看是否有(int,int)
2.看是否有可兼容的参数定义 int+int 查看是否有(double,double)
3.如果可兼容的参数定义有多个int+int,(double,int)或(int,double) 此时报错 引用不明确
在函数重载中按照如上方法进行查找。如果只有(double,double)类型,那么是都可以调用这个函数的
函数的递归调用
递归的体现就是函数自身调用函数自身,如果其中每一步都要用到前一步或前几步的结果,称为递归的,用递归过程定义的函数,称为递归函数,例如连加、连乘及阶乘等。
递归主要解决什么问题呢?
一般而言,但凡能够被迭代(循环)解决的问题,递归都可以,递归解决的问题,迭代就不一定了,递归其实是分治法的一种实现方式(一种实现思路)
分治法:
分治法是一种算法思想,分治法主要解决的问题是将大问题,进行拆分,拆分成若干个小的问题进行求解,最终将每个小问题的解进行合并。
其实,分治法就是一种暴力破解法(穷举),也是一种搜索最优答案的算法
递归的一些优缺点:
- 递归就是函数在进栈,进栈的次数多了,势必会占内存,无法避免
- 在某些问题上,递归所写的代码要比迭代写的代码少
- 在某些问题上,迭代是写不出来的,所以只能用递归
递归:先递,后归
前进段:指的就是讲问题从大化小
结束段:问题无法再继续化小,则处理当前的问题
返回段:将小问题处理完毕之后,向上返回(有些问题是不需要返回的)
常用函数
Math类
Math.E Math.PI Math.abs(a) Math.ceil(a) Math.floor(a) Math.hypot(x,y) Math.max(a,b)
Math.min(a,b) Math.pow(a,b) Math.sqrt(a) Math.random() Math.random() Math.round(a)
class Test01{
public static void main(String[] args){
System.out.println(Math.E);
System.out.println(Math.PI);
//大于指定数字的最小整数
System.out.println(Math.ceil(-2.1));
//小于指定数字的最大整数
System.out.println(Math.floor(2.3));
//求两点之间的距离 x=deltX y=deltY
System.out.println(Math.hypot(3,4));
//四舍五入
System.out.println(Math.rint(3.5));
int a=321;
String s="哈哈";
System.out.println(s.length());
// System.out.println(a.length());
}
}
String类(String不是基本数据类型而是一个类,既然是类那么肯定有其相关的函数)
查询相关:
char charAt(int index) int indexOf(int ch) int lastIndexOf(int ch) int length() substring(int beginIndex, int endIndex)
判断相关:
boolean contains(String s) boolean endsWith(String s) boolean startsWith(String prefix) int compareTo(String anotherString) boolean equals(String anotherString) boolean equalsIgnoreCase(String anotherString) boolean isEmpty()
修改相关:
注意!!!对字符串的修改永远都不是对其自身进行的修改
字符串本身是不可变的!!!
对字符串的修改往往都是新建个字符串将修改后内容赋值并返回新的字符串
String replace(char oldChar, char newChar) String toUpperCase() String toLowerCase() String trim()
class Test02{
public static void main(String[] args){
String s="abcd";
/*
"abcd"
0123
*/
//获取指定角标处的字符
System.out.println(s.charAt(0));
//判断指定子串是否包含在s中
System.out.println(s.contains("ab"));
//判断指定子串是否在s的结尾
System.out.println(s.endsWith("cd"));
//按照字典顺序比较两个字符串的大小
//返回值有负数 0 正数
//负数 前者在后者ASCII之前
//0 前者和后者相等
//正数 前者在后者ASCII之后
System.out.println("abc".compareTo("abd"));
/*
abc
abd c-d=-1
*/
System.out.println("abc".compareTo("abc"));
//比较两个字符串是否相等(比的是内容)
System.out.println("abc".equals("abc"));
//IgnoreCase忽略大小写
System.out.println("ABC".equalsIgnoreCase("abc"));
//在字符串中从左到右查找指定元素第一次出现的位置
System.out.println("abcccccd".indexOf('c'));
System.out.println("abcccccd".indexOf("cd"));
System.out.println("".isEmpty());
s="abababab";
System.out.println(s.replace('a','c'));
System.out.println(s.substring(0,3));//[0,3)
System.out.println(s.toUpperCase());
System.out.println(" abc abc abc ".trim());
}
}