Java语言基础(二)

文章目录

        • 成员变量与局部变量
      • 选择结构
        • 基本if选择结构
        • 多重if选择结构
        • 嵌套if选择结构
        • 分支结构
        • 局部变量
        • while循环
        • 初始与迭代
        • while的特点
        • do while循环
        • do while 的特点
        • do while的应用场景
        • for的特点
        • 流程控制:
        • 嵌套循环
        • 方法的定义
        • 定义的位置
        • 定义第一个方法
        • 方法的调用
        • 方法的参数
        • 形参与实参
        • 单个参数
        • 多个参数
        • 如何定义参数
        • 返回值与返回值类型
        • return 关键字
        • 递归
        • 循环阶乘
        • 递归阶乘
        • 斐波那契
        • 汉诺塔

成员变量与局部变量

  • 局部变量
  • 概念:声明在方法内部的变量,必须先赋值再使用。
  • 作用范围:定义行开始到所在的代码块结束。
  • 注意:多个变量,在重合的作用范围内,不可出现重名(命名冲突)。
  • 成员变量
  • 概念:声明在方法外部,类内部的变量,有默认值。
  • 作用范围:整个类内部使用。
  • 注意:如果和局部变量同名,局部变量优先级高。
  • 成员变量有默认值
    • byte short int long 默认值0
    • float double 0.0
    • char “0”
    • boolean false
    • 所有引用类型的默认值 null

选择结构

基本if选择结构

  • 语法

    if(布尔表达式){
    	//代码块
    }
    
  • 执行流程

    • 对布尔表达式进行判断
    • 结果为true,则先执行代码块,在执行后续代码。
    • 结果为false,则跳过代码块,直接执行后续代码。
  • 语法:

    if(布尔表达式){
    	//代码块1
    }else{
    	//代码块2
    }
    
  • 执行流程

    • 对布尔表达式进行判断
    • 结果为true,则先执行代码块1,在退出整个结构,执行后续代码
    • 结果为false,则先执行代码块2,在退出整个结构,执行后续代码
    • Math.random() [0,1)

多重if选择结构

  • 语法

    if(布尔表达式1){
    	//代码块1
    }else if(布尔表达式2){
    	//代码块2
    }else if(布尔表达式3){
    	//代码块3
    }else{
    	//代码块4
    }
    

嵌套if选择结构

  • 语法:

    if(外层表达式){
    	if(内层表达式){
    		//内层代码块1
    	}else{
    		//内层代码块2
    	}
    }else{
    	//外层代码块
    }
    

分支结构

  • 语法:

    switch(变量|表达式){
    	case 值1:
    		逻辑代码1;
    	case 值2:
    		逻辑代码2;
    	case 值n:
    		逻辑代码n;
    	default:
    		未满足时的逻辑代码
    }
    

    局部变量

    • 概念:声明在方法内部的变量,必须先赋值在使用。
    • 作用范围:定义行开始到坐在的代码块结束。
    • 注意:多个变量,在重合的作用范围内,不可出现重名(命名冲突)。

while循环

  • 语法:

    while(布尔表达式){
    	//逻辑代码(循环操作)
    }
    
  • 执行流程:

    • 先对布尔表达式进行判断,结果为true,则执行逻辑代码。
    • 本次执行完毕后,再次进行判断,结果仍旧为true,则再次执行逻辑代码。
    • 指导布尔表达式的结果为false,才会退出循环结构,执行后续代码
  • 需求:打印100遍“HelloWorld".

    package demo;
    
    public class TestWhile{
    	public static void main(String[]args){
    		int i=1;//1.初始化,计数器
    		while(i<=100){//循环条件
    			System.out.println("HelloWorld");
    			i++;//迭代部分
    		}
    	}
    }
    

初始与迭代

public class TestWhile{
	public static void main(String[]args){
		int a=1;
		int b=1;
		int c=1; //初始部分
		while(c<=100){
			System.out.println("HelloWorld");
			a++;
			b++;
			c++;//迭代部分
		}
	}
}

while的特点

  • 特点:首次即有入口条件,先判断、再执行,适用于循环次数明确的情况。
public class TestWhile{
	public static void main(String[]args){
		int i=1000;
		while(i<=100){
			System.out.println("HelloWorld");
		}
		System.out.println("程序结束");
	}
}
//计算 1 + 2 + 3 + 4 + 5 ... + 98 + 99 + 100 的总和。
public class Main{
	public static void main(String[]arrgs){
		int i=1;
		int sum=0;
		while(i<=100){
			sum+=i;
			i++;
		}
		System.out.println("result:"+sum);
	}
}
// 1 ~ 100 之间,所有偶数的和
public class Main{
	public static void main(String[]arrgs){
		int i=1;
		int evenSum=0;
		while(i<=100){
			if(i%2==0){
				evenSum+=i;
				i++
			}
		}
		System.out.println("result:"+evenSum);
	}
}

do while循环

  • 语法:

    do{
    	逻辑代码(循环操作)
    }while(布尔表达式)
    
  • 执行流程:

    • 先执行一次循环操作之后,在进行布尔表达式的判断。
    • 如果结果为true,则再次执行循环操作。
    • 如果结果为false,才会退出循环结构,执行后续代码

do while 的特点

  • 特点:首次没有入口条件**,先执行,在判断**

  • 需求:打印100遍"HelloWorld"

    public class TestDoWhile{
    	public static void main(String[]args){
    		int i=1;
    		do{
    			System.out.println("HelloWorld");
    			i++;
    		}while(i<=100);
    	}
    }
    

do while的应用场景

  • 需求:检查学生作业完成情况,输入教师评语,决定学生是否需要抄写代码

    public class TestDoWhile{
    	public static void main(String[]args){
    		Scanner scanner = new Scanner(System.in);
    		
    		char answer;//记录教师评语
    		do{
    			System.out.println("抄写一遍作业代码.....");
    			
    			System.out.println("请输入老师评语:");
    			answer=scanner.next().charAt(0);//输入y,表示及格,退出循环
    		}while(answer!='y');
    		System.out.println("作业已经完成");
    	}
    }
    
  • 应用场景:适用于循环次数不明确的情况

  • 练习

    public class Main {
    
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            String answer = null;
            do {
                System.out.println("Be my girlfriend!"); //will you be my girlfriend?
                answer = scanner.nextLine();
            } while (!answer.equals( "i do"));  // i will  , i am  willing to.
            System.out.println("Congratulations on your girlfriend");
        }
    
    }
    
    public static void main(String[] args) {
        int sum = 0;
        int number = 1;
        do {
            sum += number;
            number++;
        } while (number <= 100);
        System.out.println(sum);
    }

for的特点

  • 特点:首次即有入口条件,先判断、再执行,适用于循环次数明确的情况。

    //控制台输入整数n,计算n的阶乘(!n)。例:1 * 2 * 3 ... * n
    public class Test{
    	 public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("Please input a num;(Integer)");
            int num = scanner.nextInt();
            int result = 1;
            for (int i = 1; i <= num; i++) {
                result *= i;
            }
            System.out.println("result:" + result);
        }
    }
    
  • for的特殊使用环境

    • 1.省略循环条件
    • 省略迭代部分,出现死循环
    • 3.初始化,循环条件,迭代部分都省略,出现死循环。

流程控制:

  • continue:默认结束本次循环并不退出循环结构,而是进入下一次循环,continue也可以调到label,继续执行下一轮.

    public class TestContinue{
    	public static void main(String[]args){
    		for(int i=1;i<=10;i++){
    			if(i==5){
    				continue;
    			}
    			System.out.println("当前循环次数:"+i);
    		}
    		
    		System.out.println("循环结束。");
    	}
    }
    
  • break:终止,跳出switch,循环结构. 默认退出当前最近一个循环.加一个个标签就随便挑类似goto,实际上break会调到循环的"}"

嵌套循环

  • 概念:在一个完整的循环结构中,嵌套另一个完整的循环结构。

  • 需求:打印3行五颗星。

    public class TestNestFor{
    	public static void main(String[]args){
    		for(int i=1;i<=3;i++){
    			for(int j=1;j<=5;j++){
    				System.out.print("*");
    			}
    			System.out.println();
    		}
    	}
    }
    
    import java.util.Scanner;
    
    public class Test11 {
        //    打印直角三角形
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("Please input a num(Integer)");
            int num = scanner.nextInt();
            for (int i = 1; i <= num; i++) {
                for (int j = 1; j <= i; j++) {
                    System.out.print("*");
              }
                System.out.println();
            }
        }
    }
    
    public class Main {
    //18、读入一个整数n,输出如下图
    
    //等腰三角形
    //    n=3
    //    空2 *1
    //    空1 *3
    //    空0*5
    
    
        //    n=4
    //    空3*1
    //      空2*3
    //      空1*5
    //    空0*7
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("Please input a Number(Integer>2)");
            int n = scanner.nextInt();
            printTriangle(n);
        }
    
        private static void printTriangle(int n) {
            System.out.println("n = " + n);
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n - i; j++) {
                    System.out.print(" ");
                }
                for (int j = 1; j < 2 * i; j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    
    }
    

方法的定义

  • 概念:实现特定功能的一段代码,可反复使用。

  • 定义语法:

    public static void 方法名称(){  //遵循标识符命名规范
    	//方法主体   (功能代码)
    }
    
  • 经验:将需要在多个位置重复使用的一组代码,定义在方法内部。

  • 好处

    • 减少冗余,提高复用性,可读性,可维护性,方便分工合作

定义的位置

  • 定义的位置

    //位置1
    public class TestDefinitionFunction{
    	//位置2
    	public static void main(String[]args){
    		//位置3
    	}
    	//位置4
    }
    //位置5
    
  • 正确位置:位置2,位置4

定义第一个方法

public class TestFunction {
    public static void main(String[] args) {
        System.out.println("床前明月光");
        System.out.println("疑似地上霜");
        System.out.println("举头望明月");
        System.out.println("低头思故乡");
    }

    public static void printSign() {
        for (int i = 0; i < 10; i++) {
            System.out.print("-");
        }
        System.out.println();
    }
}

方法的调用

public class TestFunction {
    public static void main(String[] args) {
        System.out.println("床前明月光");
        printSign();
        System.out.println("疑似地上霜");
        printSign();
        System.out.println("举头望明月");
        printSign();
        System.out.println("低头思故乡");
        printSign();
    }

    public static void printSign() {
        for (int i = 0; i < 10; i++) {
            System.out.print("-");
        }
        System.out.println();
    }
}

  • 注意:调用方法时,会优先执行方法内部代码,结束后,返回到调用处,继续向下执行

方法的参数

  • 多数情况下,方法与调用者之间需要数据的交互;调用者必须提供必要的数据,才能使方法完成相应的功能
  • 调用方法时,所传入的数据被称为“参数”。

形参与实参

  • 定义语法:

    public static void 方法名称(形式参数){  //形参等价于局部变量的声明
    	//方法主体  
    }
    
  • 调用语法:

    方法名称(实际参数); //“实参”等价于局部变量的赋值

    • 作用:方法的参数可以让代码功能更加灵活,普适性更高,意于修改及维护。
  • 注意:实际参数和形参的个数,数据类型完全一致或兼容。

单个参数

public class Test16 {
    public static void main(String[] args) {
        System.out.println("床前明月光");
        printSign(10);   //实际参数:10  调用带参方法是,必须传入实际参数,为形式参数赋值
        System.out.println("疑似地上霜");
        System.out.println("举头望明月");
        System.out.println("低头思故乡");
    }
	//定义:打印count分割符的函数
    private static void printSign(int count) { // 形式参数:int count 当方法被执行时,循环count次
        for (int i = 0; i < count; i++) {
            System.out.print("-");
        }
        System.out.println();
    }
}

多个参数

public class Test17 {
    public static void main(String[] args) {
        System.out.println("床前明月光");
        // 实参:10,# 
        //调用带参方法时,一次传入实参
        //类型,个数,顺序,必须与形参对应。
        printSign(10, '#');
        System.out.println("疑似地上霜");
        System.out.println("举头望明月");
        System.out.println("低头思故乡");
    }
	//形参:int count,char sign
    //当方法被执行时,打印count次sign
    private static void printSign(int count, char sign) {
        for (int i = 0; i < count; i++) {
            System.out.print(sign);
        }
        System.out.println();
    }
}

如何定义参数

  • 经验:根据具体业务需求,来定义方法的参数

返回值与返回值类型

  • 概念:方法执行后的返回结果

  • 注意:一个方法只能返回一个结果,返回结果数据类型符合定义方法的返回类型。

  • 方法执行后,一些情况下无需返回结果;另一些情况下则必须返回结果。

    • 例如:
      • 存款操作无需返回结果
      • 取款操作必须返回结果
  • 定义语法:

    //返回值类型:规定返回值的具体类型(基本,引用,void)
    public static 返回值类型 方法名称(形式参数列表){
    	//方法主体
    	//根据需求返回一个结果(值)
    	return value; //返回值
    }
    
  • 调用语法

    • 变量=方法名称(); //变量类型与返回值类型一致。
public class Test18 {
    public static void main(String[] args) {
//        需求:定义方法,计算两个整数的和,并返回结果,在main中打印
        int result = add(5, 6);
        System.out.println(result);
    }

    public static int add(int num1, int num2) {
        return num1 + num2;
    }
}

  • 注意:方法没有返回值可以写return;

return 关键字

  • 作用

    • 返回结果

    • 结束方法

public class Test18 {
    public static void main(String[] args) {
//        需求:定义方法,计算两个整数的和,并返回结果,在main中打印
        int result = add(5, 6);
        System.out.println(result);
    }

    public static int add(int num1, int num2) {
        return num1 + num2;
        //return num1-num2; //错误:一个方法只能有一个返回值。
    }
}

public class Test19 {
    public static void main(String[] args) {
        String result = isEven(10);
        System.out.println(result);
    }

    private static String isEven(int num) {
        if (num % 2 == 0) {
            return "Even";
        } else {
            return "Odd"; //当返回值的方法存在分支结构时,必须保证每一条分支都有正确的返回值
        }
    }


}

  • return的两种用法:

    • 应用在具有返回值类型的方法中:

      • return value://表示结束当前方法,并伴有返回值,返回到方法调用处
    • 应用在没有返回值类型(void)的方法中:

      //return ;结束当前方法,直接返回到方法调用处。
      public static void show(){
      	for(int i=1;i<=100;i++){
      		if(i == 50){
      			return ;//借书当前方法直接返回
      		}
      	}
      }
      
  • 多级调用

    public class TestNestInvoke{
    	public static void main(String[]args){
    		m1();
    	}
    	
    	public static void m1(){
    		m2();
    		System.out.println("m1() -start");
    	}
    	
    	public static void m2(){
    		System.out.println("m2()-start");
    		System.out.println("m2()-end");
    	}
    }
    
  • 无穷递归

    public class TestRecursionInvoke{
    	public static void main(String[]args){
    		m1();
    	}
    	
    	public static void m1(){
    		System.out.println("m1()-start");
    		m1(); //没有正确的出口条件,产生无穷递归。
            //Exception in thread "main" java.lang.StackOverflowError
    		System.out.println("m1()-end");
    	}
    }
    
  • JVM中

    • 栈:先进后出
      • 容量大小:JDK1.5 256K JDK1.5后 1M
      • 否则会报StackOverflowError
      • 无穷递归:stack->main->m1->m2->m1->m2…StackOverflowError.

递归

  • 什么是递归?
    • 解决具有既定规律的问题时,在方法内部再次调用自身方法的一种编程方式。
  • 何时使用递归?
    • 当需要解决的问题可以拆分成若干个小问题,大小问题的解决方式相同,方法中自己调用自己
    • 使用循环解决的常规问题,都可以替换成递归解决。
  • 如何正确使用递归?
    • 设置有效的出口条件,可以让调用链上的每个方法都可以正确返回,避免无穷递归。

循环阶乘

public class Test01 {
    //     计算5的阶乘:5!= 5 * 4 * 3 * 2 * 1;
    public static void main(String[] args) {
        System.out.println(factorial(5));
    }

    private static int factorial(int n) {
        int sum = 1;
        for (int i = 2; i <= n; i++) {
            sum *= i;
        }
        return sum;
    }
}

递归阶乘

   public static void main(String[] args) {
        System.out.println(factorial(5));
    }

    private static int factorial(int n) {
        if(n==1){
            return 1;
        }
        return n*factorial(n-1);
    }
public class Test02 {
    public static void main(String[] args) {
//        使用递归完成“斐波那契数列”
//        0  1  1  2  3  5  8  13  21  34  55  ......
        System.out.println(f(3));
    }

    private static int f(int n) {
        if (n == 1) {
            return 0;
        } else if (n == 2) {
            return 1;
        }
        return f(n - 1) + f(n - 2);
    }
}

斐波那契

 public static void main(String[] args) {
        // 0 1 1 2 3
        int n = 6;
        System.out.println(feibo(6));

    }

    public static int feibo(int n) {
        if (n == 1) {
            return 0;
        } else if (n == 2) {
            return 1;
        }
        return feibo(n - 1) + feibo(n - 2);
    }

汉诺塔

//在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
// A   B    C
//1 A -->C
//2 A->B  A->C  B->C
//3   A->C  A->B C->B   A->C  B->A  B->C  A->C
//把n-1个A->B, 最大的A->C,n-2
  public static void main(String[] args) {
//        在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
//        汉诺塔
        Scanner scanner = new Scanner(System.in);
        System.out.println("Please input a number");
        int count = scanner.nextInt();
        printHannuoTower(count, 'A', 'B', 'C');
    }

    private static void printHannuoTower(int count, char sign1, char sign2, char sign3) {
        if (count == 1) {
            move(count, sign1, sign3);
            return;
        }
        //递归,把A塔上编号1~n-1的圆盘移到B上,以C为辅助塔
        printHannuoTower(count - 1, sign1, sign3, sign2);
        move(count, sign1, sign3);
        //递归,把B塔上编号1~n-1的圆盘移到C上,以A为辅助塔
        printHannuoTower(count - 1, sign2, sign1, sign3);
    }

    private static void move(int count, char sign1, char sign2) {
        System.out.println("第" + count + "移动" + ",第几个盘子" + sign1 + "----->" + sign2);
    }

你可能感兴趣的:(JavaSE)