Java笔记记录

参加歌手比赛,如果初赛成绩大于8.0进入决赛,否则提示淘汰。

 //并且根据性别提示进入男子组或女子组。
 //【可以让学员先练习下】,输入成绩和性别,进行判断和输出信息。
 [ NestedIf .java ]提示:double score ; char gender ;

  •  接收字符:char gender = scanner. next ( ) .charAt ( 0 )

 //思路分析
        //1 .创建Scanner对象,接收用户输入
        //2 .接收成绩保存到double score
        //3.使用if-else判断如果初赛成绩大于8.0进入决赛,否则提示淘汰
        //4 .如果进入到决赛,再接收char gender,使用if-else输出信息

import java.util.Scanner;
public class NestedIf{
    public static void main(String[] args){
        //代码实现
        Scanner myScanner = new Scanner(System.in);
        System.out.println("请输入该歌手的成绩");
        double score = myScanner.nextDouble();
        if( score>8.0){
            System.out.println("请输入性别");
            char gender = myScanner.next().charAt(0);
            //把字符串转为字符字符char 含义 把字符第一个字符得到
            if( gender == '男'){
                System.out.println("进入男子组");
            }else if( gender == '女'){
                System.out.println("进入女子组");
            }else{
                System.out.println("性别有误");
            }
        }else{
            System.out.println("sorry");
        }
    }
}
  •  Switch细节:

细节1

        表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的                                类型,比如输入的是字符,而常量是int

细节2

        switch (表达式)中表达式的返回值必须是: ( byte , short,int , char,enum [枚                        举],String )

细节3

        case子句中的值必须是常量( 1,' a ' ),或者是常量表达式,而不能是变量

细节4

        default子句是可以选的,当没有匹配case时,执行default

        如果没有default子句,又没有匹配任何常量,则没有输出

细节5

        break语句用来执行完一个case分支后使程序跳出switch语句块

        如果没有写break,程序会顺序执行到switch结尾

对学生成绩大于60分的,输出“合格”。低于60分的,

输出“不合格”。(注:输入的成绩不能大于100 ),提示:成绩/60

思路分析

1 .这道题,可以使用分支来完成,但是要求使用switch

2.这里我们需要进行一个转换,编程思路:

        如果成绩在[ 60,100 ],( int ) (成绩/ 60 ) = 1

        如果成绩在[ 0,60 ),( int ) (成绩/ 60 ) = 0

 

ps:这个思维是我没有的,还能这样思考🤔

import java.util.Scanner;
public class Main{
    public static void main(String []args) {
        Scanner myScanner = new Scanner(System.in);
		System.out.println("请输入成绩");
		double score = myScanner.nextDouble();
		if(score>=0&&score<=100){
			switch((int)(score/60)){
				case 0 :
					System.out.println("不合格");
					break;
				case 1 :
					System.out.println("合格");
					break;
				}
			}else{
				System.out.println("输入有误");
			}
		}
}

 根据用于指定月份

打印该月份所属的季节

3,4,5春季        6,7,8夏季        9 , 10,11秋季        12,1,2冬季

课堂练习,提示:使用穿透

思路分析

        1 .创建Scanner对象,接收用户输入

        2 .使用int month接收

        3 .使用switch来匹配,使用穿透来完成,比较简洁

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner myScanner = new Scanner(System.in);
        System.out.println("输入月份");
        int month = myScanner.nextInt();
        switch(month){
            case 3:
            case 4:
            case 5:
                System.out.println("这是春季");
                break;
            case 6:
            case 7:
            case 8:
                System.out.println("这是夏季");
                break;
            case 9:
            case 10:
            case 11:
                System.out.println("这是秋季");
                break;
            case 12:
            case 1:
            case 2:
                System.out.println("这是冬季");
                break;
            default :
                System.out.println("输入月份不对");
        }
    }
}

 switch和if的比较

1 .如果判断的具体数值不多,而且符合byte、short、int、charenum [枚举],String这6种类型。虽然两个语句都可以使用,建议使用swtich语句。

2 .其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。

  • for循环:

打印1 ~ 100之间所有是9的倍数的整数,统计个数及总和. [化繁为简,先死后活]

两个编程思想(技巧)

        1.化繁为简:即将复杂的需求,拆解成简单的需求,逐步完成

        2.先死后活:先考虑固定的值,然后转成可以灵活变化的值

/思路分析/

        打印1 ~ 100之间所有是9的倍数的整数,统计个数及总和

/化繁为简/

        ( 1 )完成输出1-100的值

        (2)在输出过程中进行过滤,只输出9的倍数 i%9==0

        (3)统计个数 定义一个变量 int count=0. 满足条件count++

        (4)总和,定义一个变量 int sum=0,满足条件时 sum+=i

/先死后活/

        (1)为了更好适应需求,把范围开始值和结束值作出变量

        (2)更进一步 9 的倍数也做成变量  int t=9

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner myScanner=new Scanner(System.in);
        int start=myScanner.nextInt();
        int end=myScanner.nextInt();
        int t=myScanner.nextInt();
        int count=0;
        int sum=0;
        for(int i=start;i<end;i++){
            if(i%t==0){
                System.out.println("i="+i);
                count++;
                sum+=i;
            }
        }
        System.out.println("count="+count);
        System.out.println("sum="+sum);

    }
}
  • while循环       

                          略

  • do while         

                          是关键字

                        先执行,再判断,至少执行一次

                        最后有一个    ;

如果张三不还钱,则债主将一直使出五连鞭,直到张三说还钱为

[ System . out .println ( "债主问:还钱吗?y / n " ) ]

do ...while化繁为简

( 1 )不停的问还钱吗?

( 2 )使用char answer 接收回答,定义一个Scanner对象

( 3 )在do-while的while判断 如果是y 就不在循环

import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner myScanner=new Scanner(System.in);
        char answer=' ';
        do{
            System.out.println("债主使出五连鞭");
            System.out.println("债主问:还钱吗?y/n");
            answer=myScanner.next().charAt(0);
            System.out.println("他的回答是:"+answer);    
        }while(answer!='y');
        System.out.println("张三还钱了");
    }
}

打印九九乘法表

 

  • 打印空心金字塔 

        思路分析:

            *                      //第一层 有 1 个 *       当前行第一个和最后一个位置都是 * ,后面同理

        *     *                   //第二层 有 2 个 *

    *             *               //第三层 有 2 个 *

*  *  *  *  *  *  *          //第四层 有 7 个 *        最后一行全部输出*

import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner myScanner=new Scanner(System.in);
        int totalLevel=myScanner.nextInt();
        for(int i=1;i<=totalLevel;i++){
            for(int k=1;k<=totalLevel-i;k++){
                // 输出*前,对应空格=总层数-当前层
                System.out.print(" ");
            }
            for(int j=1;j<=2*i-1;j++){
                //最后一行全部输出
                if(j==1||j==2*i-1||i==totalLevel){
                    System.out.print("*");
                }else{
                    System.out.print(" ");
                }
            }
            System.out.println("");//换行
        }
    }
}
  • break语句

        随机生成1-100的一个数,直到生成97这个数,看看一共用了几次

        提示使用:(int)(Math.random()*100+1           随机数的使用

         略

实现登录验证,有3次机会,如果用户名为“丁真”,密码“666 "提示登录成功,

否则提示还有几次机会,请使用for + break完成

思路分析1 .创建Scanner对象接收用户输入

2.定义String name;String passwd ;保存用户名和密码

     比较字符串用equals:   "林黛玉".equals(name)   //name是你定义的字符串

3 .最多循环3次[登录3次],如果满足条件就提前退出

4 .定义一般变量int chance记录还有几次登录机会

import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner myScanner=new Scanner(System.in);
        String name="";
        String passwd="";
        int chance=3;
        for(int i=1;i<=3;i++){
            System.out.println("请输入名字");
            name=myScanner.next();
            System.out.println("请输入密码");
            passwd=myScanner.next();
            //比较输入的名字和密码是否正确
            //比较字符串内容是否相等 用 equals
            if("丁真".equals(name)&&"666".equals(passwd)){
                System.out.println("恭喜你,登录成功");
                break;
            }
            chance--;
            System.out.println("你还有"+chance+"次登录机会");
        }
    }
}

continue:略

 

return补充:
public class Main
{
	public static void main(String[] args) {
		for(int i=1;i<=5;i++){
		    if(i==3){
		        System.out.println("狗"+i);
		        return;
		        //当return用在方法时,表示跳出方法,如果使用在main,表示退出程序
		    }
		    System.out.println("hello");
		}
		System.out.println("go on...");
	}
}

对于有小数的计算,注意分子写成小数。 

public class Main
{
	public static void main(String[] args) {
		double sum=0;
		for(int i=1;i<=100;i++){
		    if(i%2!=0){
		        sum+=1.0/i;
		        //分子写成1.0,才能计算出正确结果
		    }else{
		        sum-=1.0/i;
		    }
		}
		System.out.println("sum="+sum);
	}
}
  • 数组

数组大小/长度:  数组名. length

数组的定义: 数据类型 数组名[]=new 数据类型[大小]

                           int a[]=new int[5]

                           数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用赋值

布尔类型数组默认false

public class Main{
	public static void main(String[] args) {
		char[] chars=new char[26];
		for(int i=0;i<chars.length;i++){
		    chars[i]=(char)('A'+i);
		}
		System.out.println("===数组===");
		for(int i=0;i<chars.length;i++){
		    System.out.print(chars[i]+" ");
		}
	}
}

扩充数组

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner myScanner=new Scanner(System.in);
        int[] arr={1,2,3};
        do{
            int[] arrNew=new int[arr.length+1];
            for(int i=0;i<arr.length;i++){
            arrNew[i]=arr[i];
            }
            int addNum=myScanner.nextInt();
            arrNew[arrNew.length-1]=addNum;
            arr=arrNew;
            for(int i=0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
            }
            System.out.println("是否继续添加 y/n");
            char key=myScanner.next().charAt(0);
            if(key=='n'){
            break;
            }
        }while(true);
    }
}

找名字

编程思想:int index=-1        //判断作用 

import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		String[] names={"as","qw","si","ao"};
        Scanner myScanner=new Scanner(System.in);
        System.out.println("请输入名字");
        String findName=myScanner.next();
        int index=-1;
        for(int i=0;i<names.length;i++){
            if(findName.equals(names[i])){
                System.out.println("恭喜你找到"+findName);
                System.out.println("下标为"+i);
                //把i 保存到index
                index=i;
                break;
            }
        }
        if(index==-1){
            System.out.println("没有找到"+findName);
        }
	}
}
  • 二维数组:

        动态创建下面二维数组,并输出:

        i=0:1

        i=1:2 2

        I=2:3 3 3

        一个有三个一维数组,每一个一维数组的元素是不一样的        

public class Main{
	public static void main(String[] args) {
        int[][] arr=new int[3][];
        for(int i=0;i<arr.length;i++){
            //遍历arr每一个一维数组
            //给每一个数组开空间 new
            //如果没有给一维数组 new,那么arr[i]就是null
            arr[i]=new int[i+1];
            for(int j=0;j<arr[i].length;j++){
                arr[i][j]=i+1;
            }
        }
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arr[i].length;j++){
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
    }
}

杨辉三角

public class Yanghui{
	public static void main(String[] args) {
		int[][] arr=new int[10][];
        for(int i=0;i<arr.length;i++){
            arr[i]=new int[i+1];
            for(int j=0;j<arr[i].length;j++){
                if(j==0||j==arr[i].length-1){
                    arr[i][j]=1;
                }else{
                    arr[i][j]=arr[i-1][j]+arr[i-1][j-1];                }
            }
        }
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arr[i].length;j++){
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
	}
}

 在一个升序数组里面插入一个数字

//import java.util.Scanner;
public class Home{
	public static void main(String[] args) {
		//在一个升序数组中插入一个数
    int[] arr={10,12,45,90};
    int insertNum=23;
    int index=-1;//index就是要插入的位置
    //遍历arr,若insertNum<=arr[i],说明i是插入的位置
    //如果遍历完,没有发现 insertNum<=arr[i],说明index=arr.length
        for(int i=0;i<arr.length;i++){
            if(insertNum<=arr[i]){
                index=i;
                break;
            }
        }
        //判断index的值
        if(index==-1){
            index=arr.length;
        }   
        //扩容
        //先创建一个新数组,大小arr.length+1
        int[] arrNew=new int[arr.length+1];
        for(int i=0,j=0;i<arrNew.length;i++){
            if(i!=index){
                arrNew[i]=arr[j];
                j++;
            }else{
                arrNew[i]=insertNum;
            }
        }
        //让 arr 指向arrNew,原来的数组,就成为垃圾,被销毁
        arr=arrNew;
        for(int i=0;i<arrNew.length;i++){
            System.out.print(arrNew[i]+" ");
        }
	}
}
  •  创建对象:

                属性定义: 访问修饰符 属性类型 属性名

public class Object01{
	public static void main(String[] args) {
        //p1是对象名(对象引用)
        //new person()  创建的对象空间(数据) 才是真正的对象
		Person p1=new Person();
        System.out.println("\n当前这个人的信息");
        System.out.println("age="+p1.age+" name="
        +p1.name+" sal="+p1.sal+" isPass="+p1.isPass);
	}
}
class Person{
    int age;
    String name;
    double sal;
    boolean isPass;
}
  • 成员方法的定义:​​​​​​​

                public 返回数据类型 方法名 (行参列表){//方法体

                           语句;

                            return 返回值;

                }

               1. 形参列表:表示成员方法输入 cal(int n),getSum(num1,num2)
                2.数据类型 (返回类型):表示成员方法输出, void 表示没有返回值
                3.方法主体:表示为了实现某一功能代码块

                4.return 语句不是必须的

public class Method{
	public static void main(String[] args) {
		//方法写好后,如果不去调用(使用),不会输出
        //先创建对象,然后调用方法
        Person p1=new Person();
        p1.speak();//调用方法
        p1.cal01();//调用cal01方法
        p1.cal02(5);//调用cal02 方法,同时给n=5
        p1.cal02(10);

        int returnRes=p1.getSum(10,40);
        System.out.println("getSum方法返回的值="+returnRes);
	}
}
class Person{
    String name;
    int age;
    //方法(成员方法)
    //添加speak 成员方法,输出"我是好人"
    //1.public :表示方法是公开
    //2.void :表示方法没有返回值
    //3.speak() :speak是方法名,() 行参列表
    //{} 方法体 ,可以写要执行的代码
    public void speak(){
        System.out.println("我是好人");
    }
    //添加cal01方法,计算1+...+100的结果
    public void cal01(){
        int res=0;
        for(int i=1;i<=1000;i++){
            res+=i;
        }
        System.out.println("cal01="+res);
    }
    //再添加cal02 成员方法,该方法可以接收一个数n,计算从1+...+n 的结果
    //1. (int n) 行参列表,表示当前有一个行参n,可以接收用户输入
    public void cal02(int n){
        int res=0;
        for(int i=1;i<=n;i++){
            res+=i;
        }
        System.out.println("cal02="+res);
    } 
    //添加getSum成员方法,可以计算两个数的和
    //public表示方法是公开的
    //int :表示方法执行后返回一个int
    //(int num1,int num2) 行参列表,两个行参,可以接收用户传入的两个数
    //return res :表示把 res 的值,返回
    public int getSum(int num1,int num2){
        int res=num1+num2;
        return res;
    }
} 

 细节:

返回数据类型

1 .一个方法最多有一个返回值【思考,如何返回多个结果 ,返回数组】

2.返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)

3.如果方法要求有返回数据类型,则方法体中最后的执行语句必须为return值;而且要求返回值类型必须和return的值类型一致或兼容

4 .如果方法是void,则方法体中可以没有return语句,或者只写return ;

public class MethodDetail{
	public static void main(String[] args) {
		AA a=new AA();
        int[] res=a.getSumandSub(1,4);
        System.out.println("和="+res[0]);
        System.out.println("差="+res[1]);
	}
}
class AA{
    public int[] getSumandSub(int n1,int n2){
        int[] resArr=new int[2];
        resArr[0]=n1+n2;
        resArr[1]=n1-n2;
        return resArr;
    }
}
  •  行参列表:

1 .一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开.比如getSum ( int n1.int n2 )

2 .参数类型可以为任意类型,包含基本类型或引用类型,比如printArr ( int [ ] [ ] map )

3 .调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数!【getSum】

4 .方法定义时的参数称为形式参数,简称形参:方法调用时的传入参数称为实际参数,简称实参,实参和形参的类型要一致或兼容、个数、顺序必须一致! [演示]方法体里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义

  •  方法调用细节说明

        1.同一个类中的方法调用:直接调用即可。比如 print(参数);
           案例演示:A类 sayOk 调用 print()
        2.跨类中的方法A类调用B类方法:需要通过对象名调用。比如 对象名.方法名(参数);  

           案例演示:B类 sayHello 调用 print()
        3.特别说明一下:跨类的方法调用和方法的访问修饰符相关

public class MethodDetail{
	public static void main(String[] args) {
		A a=new A();
        a.sayOk();
        a.m1();
	}
}
class A{
    //同一类方法调用:直接调用即可
    public void print(int n){
        System.out.println("print()方法被调用="+n);
    }
    public void sayOk(){ //sayOk调用print(直接调用即可)
        print(10);
        System.out.println("继续执行sayOk()");
    }
    //跨类中的方法A类调用B类方法:需要通过对象名调用
    public void m1(){
        //创建B对象,然后再调用方法即可
        System.out.println("m1()方法被调用");
        B b=new B();
        b.hi();
        System.out.println("m1()方法继续被执行");
    }
}

class B{
    public void hi(){
        System.out.println("B类中的hi()被执行");
    }
}

 方法练习题:1.判断奇数偶数

                        2.打印

public class MethodExercise01{
    public static void main(String[] args){
        AA a=new AA();
        if(a.isOdd(1)){
            System.out.println("是奇数");
        }else{
            System.out.println("是偶数");
        }
        a.print(10,8,'*');
    }
}
//编写类AA,有一个方法:判断一个数是奇数还是偶数
class AA{
    //方法的返回类型boolean;
    //方法名 isOdd
    //方法行参(int num)
    //方法体,判断

    public boolean isOdd(int num){
        /*if(num%2!=0){
            return true;
        }else{
            return false;
        }*/

        //简化版本
        //return num%2!=0?true:false;

        //更简化
        return num%2!=0;
    }

    //根据行、列、字符打印 对应行数和列数的字符
    //思路:
    //方法的返回类型 void;
    //方法名 print
    //方法行参(int row,int col,char c)
    //方法体,循环
    public  void print(int row,int col,char c){
        for(int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                System.out.print(c);
            }
            System.out.println();
        }
    }
}

 成员方法传参机制:

引用类型传递的是地址(传递也是值,但值是地址),可以通过行参影响实参

简而言之就是对于同一个参数,如果在前面变了,main中这个参数也跟着变了

public class MethodParameter02{
    public static void main(String[] args){
        B b=new B();
        int[] arr={1,2,3};
        b.test100(arr);
        System.out.println("main的arr数组");
        for(int i=0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
        System.out.println();
    }
}
class B{
    //B类中编写一个方法test100
    //可以接收一个数组,在方法中修改数组,看原来的数组是否变化
    public void test100(int[] arr){
        arr[0]=200;
        //遍历数组
        System.out.println("test100的 arr数组");
        for(int i=0;i<arr.length;i++){
            System.out.print(arr[i]+"\t");
        }
        System.out.println();
    }
}
如果把p = null,那么不指向,所以p.age 还是10
如果new 一个新的,那么p指向的是另一个空间,就互不影响
​​​​​​​
public class MethodParameter03{
    public static void main(String[] args){
        B b=new B();
        Person p=new Person();
        p.name="jack";
        p.age=10;
        b.test200(p);
        //如果test200执行的是 p=null ,下面结果是 10
        //System.out.println("main 的p.age="+p.age);
        //如果test200执行的是 p=new Person()... ,下面结果仍为是 10
        System.out.println("main 的p.age="+p.age);
    }
}
class Person{
    String name;
    int age;
}
class B{
    public void test200(Person p){
        //p=null;
        p=new Person();
        p.name="tom";
        p.age=99;
    }
}

克隆对象:

public class MethodExercise02{
    public static void main(String[] args){
        Person p=new Person();
        p.name="milan";
        p.age=100;
        MyTools tools=new MyTools();
        Person p2=tools.copyPerson(p);

        //到此p1和p2是Person 对象,但是是两个独立的对象,属性相同
        System.out.println("p的属性 age="+p.age+" 名字="+p.name);
        System.out.println("p2的属性 age="+p2.age+" 名字="+p2.name);
    }
}
class Person{
    String name;
    int age;
}
class MyTools{
    //编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象,克隆对象
    //注意要求得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
    //
    //方法的返回类型  Person
    //方法名 copyPerson
    //方法行参 (Person p)
    //方法体,创建一个新对象,并复制属性
    public Person copyPerson(Person p){
        //创建一个新的对象
        Person p2=new Person();
        p2.name=p.name;
        p2.age=p.age;
        return p2;
    }
}

方法递归调用:

                递归的输出其实是倒着来的

public class Recursion01{
    public static void main(String[] args){
        T t1=new T();
        t1.test(4);
        int res=t1.factorial(5);
        System.out.println("res="+res);
    }
}

class T{
    public void test(int n){
        if(n>2){
            test(n-1);
        }
        System.out.println("n="+n);
    }
    //factorial 阶乘
    public int factorial(int n){
        if(n==1){
            return 1;
        }else{
            return factorial(n-1)*n;
        }
    }
}

​​​​​​​

 用递归的方法写斐波那契数列

public class RecursionExercise01{
    public static void main(String[] args){
        T t1=new T();
        int n=7;
        int res=t1.fibonacci(n);
        if(res!=-1){
            System.out.println("当n=7对应的斐波那契数="+res);
        }
    }
}

class T{
    public int fibonacci(int n){
        if(n>=1){
            if(n==1||n==2){
                return 1;
            }else{
                return fibonacci(n-1)+fibonacci(n-2);
            }
        }else{
            System.out.println("输入有误");
            return -1;
        }
    }
}

猴子吃桃问题 

public class RecursionExercise02{
    public static void main(String[] args){
        T t1=new T();
        int day=9;
        int peachNum=t1.peach(day);
        if(peachNum!=-1){
            System.out.println("第"+day+"天有"+peachNum+"个桃子");
        }
    }
}

class T{
    public int peach(int day){
        //前一天的桃子=(后一天的桃子+1)*2
        if(day==10){
            return 1;
        }else if(day>=1&&day<=9){
            return (peach(day+1)+1)*2;
        }else{
            System.out.println("day在1-10");
            return -1;
        }
    }
}

 迷宫问题:

public class MiGong{
    public static void main(String[] args){
        //1.先创建迷宫,用二维数组表示
        //2.先规定 map 数组的元素值:0 表示可以走,1 表示障碍物
        int[][] map=new int[8][7];
        //3.将最上面一行和最下面一行,全部设置为1
        for(int i=0;i<7;i++){
            map[0][i]=1;
            map[7][i]=1;
        }
        //4.将最右的一列和最左的一列,全部设置为1
        for(int i=0;i<8;i++){
            map[i][0]=1;
            map[i][6]=1;
        }
        map[3][1]=1;
        map[3][2]=1;
        for(int i=0;i<map.length;i++){
            for(int j=0;j<map[i].length;j++){
                System.out.print(map[i][j]+" ");
            }
            System.out.println();
        }
        //使用findWay 给老鼠找路

        T t1=new T();
        t1.findWay(map,1,1);

        System.out.println("\n====找路的情况====");
        for(int i=0;i<map.length;i++){
            for(int j=0;j<map[i].length;j++){
                System.out.print(map[i][j]+" ");
            }
            System.out.println();
        }
    }
}

class T{
    //使用递归回溯的思想来解决老鼠出迷宫问题
    //1.findWay方法就是专门找出迷宫的路径
    //2.如果找到,就返回 true ,否则返回 false
    //3.map 就是二维数组,即表示迷宫
    //4.i,j 就是老鼠的位置,初始位置是(1,1)
    //5.因为我们是递归的找路,所以先规定 map 数组各个值的含义
    //   0 表示可以走,1 表示障碍物,2 表示可以走,3 表示走过但是走不通
    //6.当map[6][5]=2 就说明找到通路,就可以结束,否则就继续找
    //7.先确定老鼠找路的策略 :下->右->上->左
    public boolean findWay(int[][] map,int i,int j){
        if(map[6][5]==2){
            return true;
        }else{
            if(map[i][j]==0){//当前位置是0,可以走
                //我们假定可以走通
                map[i][j]=2;
                //使用找路策略,来确定该位置是否真的可以走通
                //下->右->上->左
                if(findWay(map,i+1,j)){
                    //先走下
                    return true;
                }else if(findWay(map,i,j+1)){   //走右
                    return true;
                }else if(findWay(map,i-1,j)){   //走上
                    return true;
                }else if(findWay(map,i,j-1)){   //走左
                    return true;
                }else{
                    map[i][j]=3;
                    return false;
                }
            }else{
                //map[i][j]=1,2,3
                return false;
            }
        }
    }
}

若改变路径,改为上右下左,那么路线会改变

汉诺塔:


此代码展示的是移动过程:

public class HanoiTower{
    public static void main(String[] args){
        Tower tower=new Tower();
        tower.move(5,'A','B','C');
    }
}

class Tower{
    //方法
    // num表示要移动的个数, a,b,c分别表示 A塔,B塔,C塔
    public void move(int num,char a,char b,char c){
        //如果只有一个盘 num=1
        if(num==1){
            System.out.println(a+"->"+c);
        }else{
            //如果有多个盘,可以看成两个,最下面和最上面的所有盘
            //先移动上面所有盘到 b,借助 c
            move(num-1,a,c,b);
            //把最下面的这个盘移动到c
            System.out.println(a+"->"+c);
            //再把b塔的所有盘,移动到c,借助 a
            move(num-1,b,a,c);
        }
    }
}

八皇后问题:

             任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。​​​​​​​

  • 方法重载(overload):

java中允许同一个类中,多个同名方法的存在,但要求行参列表不一致​​​​​​​ 

比如: System.out.println();    out 是PrintStream类型

注意事项:

        使用细节:1.方法名:必须相同

                             2.行参列表:必须相同(行参类型或个数或顺序,至少有一样不同,参数名无要求)

                             3.返回类型:无要求

可变参数:

        java中允许将同一个类中多个同名同功能参数个数不同的方法,封装成一个方法。就可以通过可变参数实现。

        访问修饰符 返回类型 方法名(数据类型... 行参名){       }

细节:1.可变参数的实参可以为0个或任意多个

         2.可变参数的实参可以为数组

          3.可变参数的本质是数组

          4.可变参数可以和普通类型的参数一起放在行参列表,但必须保证可变参数在最后

         5.一个行参列表只能出现一个可变参数

public class VarParameter01{
    public static void main(String[] args){
        HspMethod m=new HspMethod();
        System.out.println(m.sum(1,5,100)); //106
        System.out.println(m.sum(1,19)); //20
    }
}

class HspMethod{
    //1. int... 表示接受的是可变参数,类型是int,即可接收多个int(0-多)
    //2. 使用可变参数时,可以当做数组来使用,即用 nums 可以当作数组
    //3.遍历 nuums 求和即可
    public int sum(int... nums){
        int res=0;
        for(int i=0;i<nums.length;i++){
            res+=nums[i];
        }
        return res;
    }
}

练习:

public class VarParameterExercise{
    public static void main(String[] args){
        HspMethod hm=new HspMethod();
        System.out.println(hm.showScore("milan",90.0,88.0));
        System.out.println(hm.showScore("min",90.1,88.0,77.6));
        System.out.println(hm.showScore("lan",90.0,34.4,66.2,32.4,50));
    }
}

class HspMethod{
    //有三个方法,分别实现返回姓名和两门课成绩
    //分别实现返回姓名和三门课成绩,分别实现返回姓名和五门课成绩
    //封装成一个可变参数的方法

    //方法名 showScore  行参(String ,double...)  返回String
    public String showScore(String name,double... scores){
        double totalScore=0;
        for(int i=0;i<scores.length;i++){
            totalScore+=scores[i];
        }
        return name+"有"+scores.length+" 门课成绩总分为="+totalScore;
    }
}

  • ​​​​​​​作用域:

        局部变量:也就是除了属性外的其他变量,作用域为定义它的代码块中

        全局变量:也就是属性,作用域为整个整体。可以不赋值,直接使用,因为有默认值,局部变量必须赋值后才能使用,因为没有默认值。


细节:

        1.属性与局部变量可以重名,访问时遵循就近原则

        2.在同一个作用域中,比如同一个成员方法中,两个局部变量,不能重名

        3.作用域范围不同:全局变量可以被本类使用,或其他类使用(通过对象调用);局部变量只能在本类中对应的方法中使用

        4.修饰符不同:全局变量(属性)可以加修饰符,局部变量不可以加修饰符

  • 构造方法/构造器:

        作用:完成对新对象的初始化

        特点:1.方法名和类名相同

                     2.没有返回值

                     3.在创建对象时,系统会自动的调用该类的构造器完成对象的初始化

        基本语法:

                [修饰符] 方法名(行参列表){ 方法体;}

public class Constructor01{
    public static void main(String[] args){
        //当我们new 一个对象时,直接通过构造器指定名字和姓名和年龄
        Person p1=new Person("smith",80);
        System.out.println("p1的信息如下");
        System.out.println("p1的对象name="+p1.name);
        System.out.println("p1的对象age="+p1.age);
    }
}

class Person{
    String name;
    int age;
    //构造器
    //1.构造器没有返回值,也不能写void
    //2.构造器的名称和类Person一样
    //3.(String pName,int pAge) 是构造器的行参列表,规则和成员方法一样
    public Person(String pName,int pAge){
        System.out.println("构造器被调用,完成对象的属性初始化");
        name=pName;
        age=pAge;
    }
}
public class ConstructorDetail{
    public static void main(String[] args){
        //第一个构造器
        Person p1=new Person("king",40);
        //第二个构造器
        Person p2=new Person("tom");
        Dog dog1=new Dog();
    }
}
class Dog{
    //如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器
    //一旦定义了自己的构造器,默认的构造器就覆盖了,就不能使用默认的无参构造器
    //除非显示的再定义一下,即Dog(){} 写(这点很重要)
    public Dog(String dName){
        //...
    }
    Dog(){
        //显示的定义一下 无参构造器
    }
}

class Person{
    String name;
    int age;
    //第一个构造器
    public Person(String pName,int pAge){
        System.out.println("构造器被调用,完成对象的属性初始化");
        name=pName;
        age=pAge;
    }
    //第二个构造器,只指定人名,不需要指定年龄
    public Person(String pName){
        name=pName;
    }
}
  • ​​​​​​​this:

​​​​​​​        哪个对象调用,this就代表哪个对象

public class This01{
    public static void main(String[] args){
        Dog dog1=new Dog("大壮",3);
        System.out.println("dog1的hashcode="+dog1.hashCode());
        dog1.info();
        System.out.println("==========");
        Dog dog2=new Dog("大黄",2);
        System.out.println("dog2的hashcode="+dog2.hashCode());
        dog2.info();
    }
}

class Dog{
    String name;
    int age;
    //构造器中的 name,age 是局部变量,不是属性
    //引出 this 关键字来解决
    public Dog(String name,int age){//构造器
        this.name=name;
        this.age=age;
        System.out.println("this.hashCode="+this.hashCode());
    }
    public void info(){//成员方法,输出属性和信息
        System.out.println("this.hashCode="+this.hashCode());
        System.out.println(name+"\t"+age+"\t");
    }
}

注意事项:

1 . this关键字可以用来访问本类的属性、方法、构造器

2 .this用于区分当前类的属性和局部变量

3 .访问成员方法的语法:this .方法名(参数列表)

4 .访问构造器语法:this (参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器)(必须放在构造器中的第一条语句)

5 .this不能在类定义的外部使用,只能在类定义的方法中使用

public class ThisDetail{
    public static void main(String[] args){
        T t1=new T();
        t1.f2();
        System.out.println("============");
        T t2=new T();
    }
}

class T{
    //细节:访问构造器语法:this(参数列表);
    //注意只能在构造器中使用(即只能在构造器中访问另外一个构造器)
    //注意:如果有访问构造器语法:this(参数列表);语法,必须放置第一条语句
    public T(){
        //这里去访问T(String name,int age)
        this("jake",100);
        System.out.println("T()构造器");
    }
    public T(String name,int age){
        System.out.println("T(String name,int age)构造器");
    }


    //访问成员方法的语法:this .方法名(参数列表)
    public void f1(){
        System.out.println("f1()方法...");
    }
    public void f2(){
        System.out.println("f2()方法...");
        //调用本类的f1
        //第一种方式
        f1();
        //第二种方式
        this.f1();
    }
}

 练习:

public class thisTestPerson{
    public static void main(String[] args){
        Person p1=new Person("mary",20);
        Person p2=new Person("amith",39);
        System.out.println("p1和p2比较多的结果="+p1.comparaTo(p2));
    }
}

/*
定义Person类,里面有name、age属性,并提供compareTo比较方法,
用于判断是否和另一个人相等,提供测试类TestPerson用干测试,
名字和年龄完全一样,就返回true,否则返回false
*/
class Person{
    String name;
    int age;
    //构造器
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    //comparaTo 比较方法
    public boolean comparaTo(Person p){
        //if(this.name.equals(p.name)&&this.age==p.age){
        //    return true;
        //}else{
        //    return false;
        //}
        //简洁版
        return this.name.equals(p.name)&&this.age==p.age;
    }
}

​​​​​​​

public class Homework01{
    public static void main(String[] args){
        A01 a=new A01();
        double[] arr=null;//{};
        Double res=a.max(arr);
        if(res!=null){
            System.out.println("arr的最大值="+a.max(arr));
        }else{
            System.out.println("arr的输入有误,数组不能为null, 或者{}");
        }
    }
}
//思路分析
//1.类名 A01
//2方法名 max
//3.形参 (double[])
//4.返回值 double
class A01{
    //Double是double类型的封装类,小写的是基本数据类型返回null会报错,
    //但是大写的Double为类可以是null
    public Double max(double[] arr){
        //保证arr至少有一个元素
        //先判断arr是否为空,再判断length 是否为0
        if(arr!=null&&arr.length>0){
            double max=arr[0];//假定第一个元素就是最大值
            for(int i=1;i<arr.length;i++){
                if(max<arr[i]){
                    max=arr[i];
                }
            }
            return max;//double
        }else{
            return null;
        }
    }
}
public class Homework02{
    public static void main(String[] args){
        String strs[]={"jske","sd","mary","milan"};
        A02 a=new A02();
        int index=a.find("milan",strs);
        System.out.println("查找是index="+index);
    }
}
//思路分析
//1.类名 A02
//2方法名 find
//3.形参 (String,String[])
//4.返回值 int
class A02{
    public int find(String findStr,String[] strs){
        //直接遍历
        for(int i=0;i<strs.length;i++){
            if(findStr.equals(strs[i])){
                return i;
            }
        }
        return -1;
    }
}

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值