1 方法(函数)
(1) 什么是方法呢?
方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
(2)方法的优点
- 1. 使程序变得更简短而清晰。
- 2. 有利于程序维护。
- 3. 可以提高程序开发的效率。
- 4. 提高了代码的重用性。
(3)方法的命名规则
.1方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
2.下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test<MethodUnderTest>_<state>,例如 testPop_emptyStack。
(4)方法的定义
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){
... 方法体 ...
return 返回值;(return 作用 1: 结束方法即遇到方法后结束函数,后面的不在执行。2 返回一个值)
}
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
实例
下面的方法包含 2 个参数 num1 和 num2,它返回这两个参数的最大值。
/** 返回两个整型变量数据的较大值 */
-
public static int max(int num1, int num2) {
-
int result;
-
if (num1 > num2)
-
result = num1;
-
else
-
result = num2;
-
return result;
-
}
(5)方法调用
Java 支持两种调用方法的方式,根据方法是否返回值来选择。
当程序调用一个方法时,程序的控制权交给了被调用的方法。当被调用方法的返回语句执行或者到达方法体闭括号时候交还控 制权给程序。
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30, 40);
如果方法返回值是void,方法调用一定是一条语句。例如,方法println返回void。下面的调用是个语句:
System.out.println("欢迎访问菜鸟教程!");
示例
下面的例子演示了如何定义一个方法,以及如何调用它:
public class TestMax {
/** 主方法 */
public static void main(String[] args) {
int i = 5; int j = 2; int k = max(i, j);
System.out.println( i + " 和 " + j + " 比较,最大值是:" + k);
}
/** 返回两个整数变量较大的值 */
public static int max(int num1, int num2) {
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
}
以上实例编译运行结果如下:
5 和 2 比较,最大值是:5
这个程序包含 main 方法和 max 方法。main 方法是被 JVM 调用的,除此之外,main 方法和其它方法没什么区别。
main 方法的头部是不变的,如例子所示,带修饰符 public 和 static,返回 void 类型值,方法名字是 main,此外带个一个 String[] 类型参数。String[] 表明参数是字符串数组。
2 递归
递归是一种常见的解决问题的方法,即把问题逐渐简单化,递归的基本思想是自己调自己,一个使用递归技术的方法将会直接或者间接的调用自己。
递归结构包括两个部分:
递归头。即什么时候不调用自身方法。如果没有头,将陷入死循环
递归体。即什么时候需要调用自身的方法
(1)什么是递归?
在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了两个意思:递 和 归,这正是递归思想的精华所在。
(2)递归思想的内涵(递归的精髓是什么?)
正如上面所描述的场景,递归就是有去(递去)有回(归来),如下图所示。“有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,“有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,就不用再往更小、更远的地方走下去。最后,从这个临界点开始,原路返回到原点,原问题解决。
更直接地说,递归的基本思想就是把规模大的问题转化为规模小的相似的子问题来解决。特别地,在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况,这也正是递归的定义所在。格外重要的是,这个解决问题的函数必须有明确的结束条件,否则就会导致无限递归的情况。
(3)递归的三要素
1). 明确递归终止条件
我们知道,递归就是有去有回,既然这样,那么必然应该有一个明确的临界点,程序一旦到达了这个临界点,就不用继续往下递去而是开始实实在在的归来。换句话说,该临界点就是一种简单情境,可以防止无限递归。
2). 给出递归终止时的处理办法
我们刚刚说到,在递归的临界点存在一种简单情境,在这种简单情境下,我们应该直接给出问题的解决方案。一般地,在这种情境下,问题的解决方案是直观的、容易的。
3). 提取重复的逻辑,缩小问题规模*
我们在阐述递归思想内涵时谈到,递归问题必须可以分解为若干个规模较小、与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。从程序实现的角度而言,我们需要抽象出一个干净利落的重复的逻辑,以便使用相同的方式解决子问题。
(4)递归算法的编程模型
在我们明确递归算法设计三要素后,接下来就需要着手开始编写具体的算法了。在编写算法时,不失一般性,我们给出两种典型的递归算法设计模型,如下所示。
模型一: 在递去的过程中解决问题
function recursion(大规模){
if (end_condition){
// 明确的递归终止条件 end; // 简单情景 }
else{
// 在将问题转换为子问题的每一步,解决该步中剩余部分的问题 solve;
// 递去 recursion(小规模);
// 递到最深处后,不断地归来
}
}
模型二: 在归来的过程中解决问题
function recursion(大规模){
if (end_condition){
// 明确的递归终止条件 end;
// 简单情景 }
else{
// 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题 recursion(小规模);
// 递去 solve;
// 归来
}
}
实例
package part1;
public class TestFactorial {
public static void main(String[] args) {
int result = new TestFactorial().factorial(5);
System.out.println(result);
}
public int factorial(int n){
if(n==1){ //递归头
return 1;
}else{
return n*factorial(n-1); //递归体
}
}
}
结果 120
(6)递归的应用场景
在我们实际学习工作中,递归算法一般用于解决三类问题:
A. 问题的定义是按递归定义的(Fibonacci函数,阶乘,…);
B. 问题的解法是递归的(有些问题只能使用递归方法来解决,例如,汉诺塔问题,…);
C. 数据结构是递归的(链表、树等的操作,包括树的遍历,树的深度,…)。
3 包的用法
(1)为什么需要package
A:为了解决类之间的重名23问题
B:为了便于管理类,合适的类位于合适的包
(2)package怎么用
通常是类的第一句非注释性的语句
包名命名规则:域名倒着写,载加上模块名,并与内管理类。
注意事项:(1)写项目时都要加包,不要使用默认包
(2)包名之间没有包含关系,只要不同名就行。如com.zhu和com.zhu.car.没有任何关系,只不过两者在表面上看起来是包含关系其实没有其他任何关联
(3)JDK注要的包
java.lang包含Java核心类如:String ,Math,Integer,System和Thread
Java.awt包含了构成抽象窗口工具类(abstract window toolkits)的多个类,这些类被用来构建和管理应用开发的图形用户界面
Java.net 包含执行与网络有关的操作类
Java.util包含一些使用工具类,如定义系统特性,使用与日期日历有关的函数
4 生成API文档
(1)特殊注释:
文档注释:/**
(2)使用Javadoc生成API文档
解决问题:代码和文档的分离
(3)常用注释标签:
@Author作者
@version版本
@param参数
@return 返还值的含义
@throws抛出异常描述
..........................................
5 接受键盘输入
(1)Scanner类
首先要引入包import java.util.Scanner;
它是一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。Scanner 使用分隔符模式将其输入分解为标 记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。
Scanner reader=new Scanner(System.in);
然后reader对象调用下列方法(函数),读取用户在命令行输入的各种数据类型
next.Byte(),nextDouble(),nextFloat,nextInt(),next(),nextLine(),nextLong(),nextShot()
上述方法执行时都会造成堵塞,等待用户在命令行输入数据回车确认.例如,拥护在键盘输入
12.34,hasNextFloat()的值是true,而hasNextInt()的值是false. NextLine()等待用户输入一个文
本行并且回车,该方法得到一个String类型的数据。
例如,以下代码使用户能够从 System.in 中读取一个数:
Scanner scanner = new Scanner(System.in);
String string = scanner.next(); //程序运行到next()会阻塞等待输入
System.out.println("键盘刚才输入的是:"+string);
实例 :
package part1;
import java.util.Scanner;
/**
* 测试Scanner类的使用,如何接收键盘的输入
* @author
*
*/
public class TestScanner {
public static void test01(){
Scanner scanner = new Scanner(System.in);
String string = scanner.next(); //程序运行到next()会阻塞等待输入
System.out.println("键盘刚才输入的是:"+string);
}
/**
* 使用nextInt()和next()以及nextline()函数
*/
public static void test02(){
Scanner scanner= new Scanner(System.in);
System.out.println("请输入一个整数:");
int a = scanner.nextInt(); //Scanner对象点nextInt()输入的是整数
System.out.println("请输入另一个加数:");
int b = scanner.nextInt();
System.out.println("两次输入的数之和为:"+(a+b));
String string = scanner.next();//Scanner对象点next()输入的是字符串
System.out.println("next()函数获得输入"+string);
Scanner scanner2 = new Scanner(System.in);
String string2 = scanner2.nextLine();
System.out.println("next()函数获得输入"+string2);
}
/*
* 使用hasNextDouble()连续输入
*/
public static void test03(){
System.out.println("请输入若干个数,每输入一个数用回车确认");
System.out.println("最后输入一个非数字结束输入操作");
Scanner reader=new Scanner(System.in);
double sum=0;
int m=0;
while(reader.hasNextDouble())
{
double x=reader.nextDouble();
m=m+1;
sum=sum+x;
}
System.out.printf("%d个数的和为%f\n",m,sum);
System.out.printf("%d个数的平均值是%f\n",m,sum/m);
}
/**
*
逐行扫描文件,并逐行输出
*/
public static void test04(){
//.....
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
System.out.println(cin.next());
}
}
public static void main(String[] args) {
TestScanner testScanner = new TestScanner();
testScanner.test02();
// testScanner.test03();
}
}
结果请输入一个整数:
1
请输入另一个加数:
2
两次输入的数之和为:3
1 3 3
next()函数获得输入1
12 w4 4
next()函数获得输入 12 w4 4
从上可以看出next() 与 nextLine() 区别
next():
- 1、一定要读取到有效字符后才可以结束输入。
- 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取:
实例public static void test05(){
Scanner scan = new Scanner(System.in);
// 从键盘接收数据
int i = 0;
float f = 0.0f;
System.out.print("输入整数:");
if (scan.hasNextInt()) {
// 判断输入的是否是整数
i = scan.nextInt();
// 接收整数
System.out.println("整数数据:" + i);
} else {
// 输入错误的信息
System.out.println("输入的不是整数!");
}
System.out.print("输入小数:");
if (scan.hasNextFloat()) {
// 判断输入的是否是小数
f = scan.nextFloat();
// 接收小数
System.out.println("小数数据:" + f);
} else {
// 输入错误的信息
System.out.println("输入的不是小数!");
}
scan.close();
}
输入整数:12.2
输入的不是整数!
输入小数:小数数据:12.2