JavaSE入门笔记

253 阅读33分钟

一、JAVA背景知识

0、学习视频

老师讲的很详细,很有趣,推荐学习。

java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题)

1、java入门知识

1.java背景知识

  • Java是美sun公司,1995年推出的计算机高级编程语言
  • 2009,被Oracle甲骨文收购

2.java能做?

应用类型示例
桌面应用开发各种税务管理软件、idea
企业级应用开发微服务、大型互联网应用
移动应用开发android、医疗设备
服务器系统应用后台
大数据开发hadoop
游戏开发我的世界

3.Java技术体系

技术体系说明
Java SE (Java Standard Edition):标准版Java技术的核心和基础
Java EE (Java Enterprise Edition):企业版企业级应用开发的一套解决方案
Java ME(Java Micro Edition ):小型版针对移动设备应用的解决方案

2、Java快速入门

1.JDK相关

  • JDK(Java Development Kit)java开发者工具包

  • JDK(8.0、LTS):Long-term support 长期支持版

  • JDK17下载路径

CMD中:

命令作用
java
javac
查看是否安装成功
java -version查看版本
java.exe执行工具
javac.exe编译工具
Java程序是高级语言,计算机底层不识别
先用javac翻译工具翻译,java.exe执行工具执行,驱动机器

2.命令行窗口常用命令

命令作用
盘符:切换盘 F:
dir查看当前路径下文件信息
cd进入单极目录 cd in
进入多级目录 cd F:\my\Javase
回到上级目录 cd ..
退回到盘符目录 cd \
cls清屏

3.入门程序

java开发三步骤:编写代码--->编译代码-->运行代码

写好HelloWorld.java,打开cmd,进入文件存放位置,javac XX.java;可以使用TAB键补全文件名;

javac HelloWorld.java
java HelloWorld

3、Java执行原理,bug设计

编程语言发展历程

  • 机器语言
  • 汇编语言
  • 高级语言:接近人类语言,好学

1.java执行原理

不管是什么高级语言,最终都是翻译成计算机底层可识别的机器语言

2.机器语言组成:01

4、JDK组成,跨平台原理

1.JDK组成

JVM(Java Virtual Machine)java虚拟机,真正运行java程序的地方
核心类库java准备好的程序,随时调用
JRE(Java Runtime Environment)java运行环境,由上面二者组成
JDKjava开发工具包,包括上面所有,和开发工具

2.JAVA执行顺序

开发工具编译javac--》Hello.java生成--》Hello.class-->工具java执行--》放入JVM运行--》调用核心类库的方法

3.跨平台原理

拥有对应不同平台系统的JVM虚拟机,实现一次编译,到处运行

5、JDK安装后Path和JAVA_HOME配置

1.Path环境变量

用于记住程序路径,方便命令行窗口任意目录启动程序

C:\Program Files\Java\jdk1.8.0_211\bin;

C:\Program Files\Java\jdk1.8.0_211\jre\bin;

2.JAVA_HOME

C:\Program Files\Java\jdk1.8.0_211;

6、IDEA开发工具

1.下载(不要安装在有空格或中文路径下)

IDEA下载路径

2.IDEA项目结构介绍

由上到下包含:

project项目、工程
module模块
package
class

建立工程、模块、包的方法

建一个空工程流程new ProjectEmpty Project
建一个新模块new module选择java模块
建包包名是网站网址倒写com.yanf.www

3.调整主题

Settings --》Appearance--》Theme

4.调整字体

Settings --》Font

5.IDEA快捷键

IDEA快捷键.png

6.IDEA其他操作

6.1修改模块名称

要磁盘和文件中一起改module and directory

6.2导入模块

file --》new--》module from existing Source --》选中模块内带黑点的文件

导入模块.png

以上存在问题,导入模块位置改变,可能丢失;

建议创建新模块,将com下文件直接复制过来;

6.3删除模块

  1. 找到文件删除

  2. 选中,上方删除(删不干净,进入模块xml中删除配置,重启IDEA)

删除模块.png

RecordDate:2021/08/06

二、Java基础语法

1.注释

java文件通过javac编译生成class文件中并不会存在注释内容

工程下的out文件中可以找到编译后的class文件,可以拖到idea中反编译显示

//普通注释


/*
多行注释
*/

/**
*
*文档注释:内容可以自动提取到程序说明书
*/
快捷注释效果
Ctrl + /单行注释
Ctrl + Shift + /对选中代码多行注释

2.字面量

字面量常用数据.png

3.变量

3.1什么是变量?

  • 变量是用来存储一个数据的内存区域,里面存储数据可变
  • 变量定义格式:
    • 数据类型 变量名称 = 初始值;

3.2变量使用注意

  • //1.变量声明后再用
  • //2.变量声明后不能存储其他类型数据
  • //3.变量有效范围从定义开始到”}“截止;
  • 同一范围不能有同名变量
  • //4.变量定义时可以没有初始化值,使用时必须赋值

4.变量在计算机中底层原理

4.1二进制

逢二进一

十进制转二进制计算方法:除二取余,从下往上倒取值;

4.2计算机中数据最小单位

  • 计算机最小组成单元
    • 使用8个二进制位为一组,存数据,为一个字节(byte,简称B)
  • 每个二进制位为一位(bit,简称b)
  • 1byte=8bit,1B=8b

4.3字符在计算机中如何存储

ASCII编码表:美国信息交换标准码

//a=97        
char a = 'a';
//a+1=98        
System.out.println(a+1);
字符做运算,会用编码参加,返回数字

ASCII编码表.png

5.进制转换

5.1二进制和十进制互相转换

5.2八进制和十六进制

  • 八进制每一位扩展成三位二进制

    • 93 135(八进制) 001-011-101(二进制)
  • 十六进制,0-9 ABCDEF

    • 97 61(十六进制) 0110-0001(二进制)
    • 93 5D(十六) 0101-1101(二)
  • 程序中支持书写二、八、十六进制数据

    • 分别需要以0B或者0b、0、0X或者0x开头

    •         int z = 0b01011101;
              System.out.println(z);
              int x = 0135;
              System.out.println(x);
              int c = 0x5D;
              System.out.println(c);
      =============
          93
      

5.3数据大小单位换算

大单位小单位
1B8B
1KB1024B
1MB1024KB
1GB1024MB
1TB1024GB

6.数据类型

6.1数据类型分类

  • 引用数据类型(除基本形外)

  • 基本数据类型:四大类8种

    • Double采用特殊计数法,范围更大

    • 随便写一个大整数需要在后面用L或l标识为Long,因为整数默认是int型

      int p= 154646546;
      //Long p1 = 46546545456465;
      Long p2 = 136458416315635631L;
      
    • 小数默认是双精度Double型,用单精度Float时,需要数字后标记F或者f

      •     double q = 45.96;
        //float f = 45.8;
        float ff = 45.8F;
        

基本数据类型.png

6.2理解float和double、单精度和双精度

1.内存占用

占用字节总位数备注
float4个字节32位1位4个0000
double8个字节64位因此,能用float尽量不用double。

2.范围

范围
float-2^128 ~ 2^127
double-2^1024 ~ 2^1023

3.为什么浮点数会有精确度问题? 浮点数是用二进制数据的科学计数法表示的,因此不能精确的表示。就像十进制1/3 0.3333…一样

4.float 32位,double64位是怎么组成的?

float1位符号位8位指数位23位尾数
double1位符号位8位指数位52位尾数

5.有效位数

有效位数备注
float6位小数点后6位都是准确的,而第7位就不一定
double15位

6.关于单精度和双精度的命名? 为什么叫单精度,为什么叫双精度 1)是因为精确度位数的区别而命名的吗?

–不是,至少没有资料表明,它是以这个来命名的。 2)是因为二进制科学计数法存储的尾数(float尾数23,double尾数52)的单双来命名吗?–好像也不是。 所以,只要记住单精度是float,双精度是double就好了。

7.关键字和标识符

7.1关键字

不能用来作为类名或者变量名称 关键字.png

7.2标识符

给类,方法,变量起名的规矩

  • 标识符要求
    • 基本要求:由数字,字母,下划线,$组成
    • 强制要求:不能以数字开头,不能是关键字,区分大小写
  • 命名规范
    • 驼峰式:
      • 变量首字母小写
      • 类名称,首字母大写

RecordDate:2021/08/06

三、类型转换

1.自动类型转换

概念:类型范围小的变量,直接赋值给类型范围大的变量

自动类型转换底层原理

​ a存八位;b占32位,把a直接放在后面,前方补0;

/**
 * 自动类型转换
 */
public class TypeDemo {
    public static void main(String[] args) {
        byte a = 20;
        int b =a;
    }
}

自动类型转换由小到大的顺序:

byte-->short(char)-->int-->long-->float-->double

        char ch ='a';
        int chq = ch;//97
        System.out.println(ch+"and"+chq);//aand97

2.表达式的自动类型转换

表达式中,小范围类型会自动转换成当前较大范围类型再运算

byte、short、char-->int-->long-->float-->double

注意:

  • 结果由最高类型决定
  • 表达式中,byte、short、char直接转换为int参与运算
        //面试题:计算中,byte直接当int,预防结果值过大
        byte op=10;
        byte opp=20;
//        byte ropp = op+opp;
        byte ropp = (byte) (op+opp);
        int ropp2 = op+opp;

3.强制类型转换

大范围变量强行赋给小范围变量,有丢失精度风险;

/**
 * 强制类型转换
 */
public class TypeDemo3 {
    public static void main(String[] args) {
        int a=5;
        byte b = (byte) a;

        int c = 1500;
        byte d = (byte) c;
        System.out.println(c+"and"+d);//1500 and -36
        
        double c1 = 1500.2699;
        int d1 = (int) c1;
        System.out.println(c1+"and"+d1);//1500.2699 and 1500
    }
}

强制类型转换底层原理:

整数:把后面的位数强行转给小范围变量;
小数:直接截断小数后位数,转成整数;

四、运算符

1.基本运算符

/**
 * 基本加减乘除
 */
public class OperatorDemo1 {
    public static void main(String[] args) {
        int a=9;
        int b=5;
        System.out.println(a + b);
        System.out.println(a - b);
        System.out.println(a * b);
        System.out.println(a / b);//1
        System.out.println(a*1.0 / b);//1.8
        System.out.println(3 / 2);//1
        System.out.println(3*1.0 / 2);//1.5;该方法用来取小数
        System.out.println(3 / 2*1.0);//1.0;
        System.out.println(a % b);//余数:4
    }
}

2.数值拆分

/**
 * 基本数据拆分
 */
public class OperatorDemo2 {
    public static void main(String[] args) {
        int a=987;
        int b,c,d;

        b=a % 10;
        c=a / 10 % 10 ;
        d=a/100;
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
    }
}

3.连接符

/**
 * 连接符
 * ''字符在一定条件下参与运算
 * “ ”字符串不参与运算
 */
public class OperatorDemo3 {
    public static void main(String[] args) {
        int a =5;
        char b ='爱';
        String china ="中国";
        System.out.println(a+b+china);//29238中国
        System.out.println(a+""+b+""+china);//5爱中国
        System.out.println(5+a);//10
        System.out.println("abc"+a);//abc5
        System.out.println("afasdf"+'a'+a);//afasdfa5
        System.out.println("afasdf"+('a'+a));//afasdf102
        System.out.println('a'+a);//5+97=102
        System.out.println('a'+""+a);//a5
        System.out.println(a+""+'a');//5a
    }
}

4.自增自减运算符

  • 注意:
  • ++和--,可以放在变量的前方和后方
  • 只能操作变量,不能操作字面量
  • 不是单独使用,前后意义不同
    • 变量前,先+1,再运算
    • 变量后,先运算,再+1
/**
 * 自增自减
 */
public class OperatorDemo4 {
    public static void main(String[] args) {
        int a =5;
        int rs = a++;//5
        System.out.println(a+"and"+rs);//6and5
        int b =5;
        int rs2 =++b;//6
        System.out.println(b+"and"+rs2);
    }
}

4.1.自增自减扩展(面试)

        System.out.println("===========扩展(面试)============");
        int k=5;//6 7 6
        int p=5;//4  3 4
        //  kp = 5   + 7   -  4  + 4   - 7   +  4  + 2
        int kp = k++ + ++k - --p + p-- - k-- + ++p + 2;
        System.out.println(k);//6
        System.out.println(p);//4
        System.out.println(kp);//11

5、赋值运算符

扩展赋值运算符.png

/**
 * 赋值运算符
 */
		int a=10;
        int b=100;
        a=a+b;
        a+=b;

        byte c=10;
        byte d=20;
        c= (byte) (c+d);
        c+=d;//byte

6.关系运算符

关系运算符.png

7.逻辑运算符

逻辑运算符.png

短路逻辑运算符.png

        /**
         * 逻辑运算符
         */
        int a=10;
        int b=100;
        System.out.println(a>20&b>100);//false
        System.out.println(a<10&b<100);//false
        System.out.println(a<=10|b<100);//true
        System.out.println(!true);//false
        System.out.println(false^true);//true
        System.out.println(false^false);//false
        /**
         * 短路逻辑运算符
         */
        System.out.println(a<10 && ++b>100);//false
        System.out.println(a==10 && ++b>100);//true b101
        System.out.println(a==10 || ++b>100);//true b101  前方正确,后方不执行
        System.out.println(a<10 || ++b>100);//true b102

8.三元运算符

格式:条件表达式?值1:值2;

执行流程:计算表达式结果;true,返回值1;否则值2.

 /**
         * 三元运算符
         */
        double score = 95.5;
        String rs = score >=60 ? "通过":"挂科";
        System.out.println(rs);

        //输出较大的值
        int a=5;
        int b=15;
        int c = a>b ? a:b;
        System.out.println("较大值:"+c);

        //三个值取最大
        int q=5;
        int w=15;
        int e=88;
        int tempMax = q>w ? q:w;
        int Max = tempMax>e ? tempMax:e;
        System.out.println("Max:"+Max);

        //简化上式
        Max = q>w ? q>e ? q:e :w>e ? w:e;
//        Max = q>w ? (q>e ? q:e) :(w>e ? w:e);
        System.out.println("Max:"+Max);

9.运算符:优先级

运算符:优先级.png

        /**
         * 运算符:优先级
         */
        System.out.println(10>3 || 10>3 && 10<3 );//true.先执行&&,false || true
        System.out.println((10>3 || 10>3) && 10<3 );//false.先执行(),true && false

10.API:键盘录入

  • API(Application Programming Interface)应用程序编程接口:
  • Java功能代码;
  • API文档(技术使用说明书);
  • API文档下载
        /**
         * 键盘输入API:Scanner
         */
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的姓名:");
        //scanner.next();等待用户输入完成
        String name = scanner.next();
        System.out.println("请输入您的年龄:");
        int age = scanner.nextInt();
        System.out.println("身份录入成功姓名:"+name+"  年龄:"+age);

RecordDate:2021/08/06

五、程序流程控制

1.流程控制语句

控制程序的执行流程;

顺序结构分支结构循环结构
默认iffor
switchwhile
do while

2.分支结构

2.1 if分支(适合区间匹配)

三种格式:

public class IfDemo {
    public static void main(String[] args) {
        /**
         * If判断
         */
        //心跳60-100正常,否则要检查
        int heartBeat=30;
        if (heartBeat<60 || heartBeat>100){
            System.out.println("心跳数据是:"+heartBeat+"需要检查");
        }

        //转账
        double money=100;
        if (money<=100){
            System.out.println("转账成功");
        }else {
            System.out.println("余额不足");
        }

        //打分 >90 A+;>=80 A;>=70 B;>=60 C;<60 D
        int score = 98;
        if (score>90){
            System.out.println("成绩为:A+");
        }else if (score>=80){
            System.out.println("成绩为:A");
        }else if (score>=70){
            System.out.println("成绩为:B");
        }else if (score>=60){
            System.out.println("成绩为:C");
        }else {
            System.out.println("成绩为:D");
        }
    }
}

2.2 switch分支(适合值匹配)

  • switch注意事项:

  • 表达式类型只能是byte、short、int、char,

  • JDK5开始支持枚举,

  • JDK7开始支持String;

  • 不支持double、float、long;

  • case值不能重复,只能是字面量,不能是变量;

  • 不能忘记写break,会出现穿透现象

    • 穿透现象:没有遇到break,执行下一case,直到遇到break;

    • 可以解决代码冗余,多个条件有相同结果可以共用

      •         switch(weekDay){
                    case "周一":
                    case "周二":
                    case "周三":
                        System.out.println("打牌");
                        break;
                    default:
                        System.out.println("沉迷打牌,不可自拔(^_^)");
                }
        

2.3执行流程:

  1. 执行表达式,结果与case匹配
  2. 匹配成功哪条就执行,遇到break跳出
  3. case值都不匹配,执行default
public class SwitchDemo {
    public static void main(String[] args) {
        /**
         * Switc
         */
        //胡适之日记展示
        String weekDay = "周四";
        switch(weekDay){
            case "周一":
                System.out.println("读书");
                break;
            case "周二":
                System.out.println("打牌");
                break;
            case "周三":
                System.out.println("打牌");
                break;
            case "周四":
                System.out.println("胡适之啊,胡适之,你怎么如此堕落,要努力读书啊!");
                break;
            case "周五":
                System.out.println("打牌");
                break;
            default:
                System.out.println("沉迷打牌,不可自拔(^_^)");
        }
    }
}

3.循环结构

3.1 for循环

        /**
         * 求1-10的奇数和
         */
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            if (i%2 ==1 ){
                sum+=i;
            }
        }

        for (int i = 0; i < 10; i+=2) {
                sum+=i;
        }

        /**
         * 水仙花数:三位数  and 个十百的数字立方和等于原数
         */
        for (int i = 100; i <999 ; i++) {
            int a = i/100;
            int b = i/10%10;
            int c = i%10;
            int count = 0;
            if ((a*a*a + b*b*b + c*c*c) == i){
                count++;
                System.out.println(i+"\t");
            }
            System.out.println("水仙花个数:"+count);
        }
    }

3.2 while循环

while和for功能上一样;

使用:直到循环多少次,用for;不知道多少次,while

/**
         * 纸张折叠多少次可以超过珠穆朗玛峰
         */
        double peakHeight=8848868;
        double paperThickness=0.1;
        int count=0;
        //while内条件成立才可以执行,完成后跳出
        while (paperThickness < peakHeight){
            paperThickness *= 2;
            count++;
        }
        System.out.println(count+"次,可以超过珠峰");
        //for代替
        //for (;paperThickness < peakHeight;){

3.3 do while循环

特点:一定会先执行一次循环体

/**
         * 抢票:
         *   先抢一次,再判断
         */
        int i=0;
        do {
            System.out.println("没抢到票,继续");
            i++;
        }while (i<3);
        System.out.println("抢票成功");

3.4总结

  • 三种循环区别:
    • for和while,先判断,后执行
    • do while 先执行一次,再判断
  • for和while区别:
    • 执行流程一样
    • 已知循环次数,用for;不知,while
    • for中,变量只能在循环内用;while结束后可以继续用;

4.死循环、循环嵌套

4.1死循环

  /**
         * 死循环
         *
         */
/*        for (;;){
            System.out.println("死循环");
        }*/

        //经典死循环
        while(true){
            System.out.println("死循环");
        }

/*        do {
            System.out.println("死循环");
        }while (true){
            System.out.println("死循环");
        }*/
 /**
         * 死循环:
         * 用户不断输入密码,直到正确
         */
        int PassWord = 520;
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("请输入正确密码:");
            int pass = scanner.nextInt();
            if (pass == PassWord){
                System.out.println("登录成功");
                break;
            }else {
                System.out.println("密码错误");
            }
        }

4.2循环嵌套

  • 循环嵌套
    • 循环包循环
  • 特点
    • 外部循环一次,内部循环全部
        /**
         * 嵌套循环
         *    五天,每天吃三顿饭
         */
        for (int i = 1; i <=5; i++) {
            System.out.println("第"+i+"天,开始");
            for (int j = 1; j <=3; j++) {
                System.out.println("吃第"+j+"顿饭");
            }
            System.out.println("=============第"+i+"天,结束==================");
        }

5.跳转控制语句

  • break:跳出并结束当前所在循环
  • continue:跳出当前循环的当次执行,进入下一次循环
    • 只能在循环中使用
 /**
         * 准备写5天日记,第三天后不写了,
         */
        for (int i = 1; i < 6; i++) {
            System.out.println(i+"天日记");
            if (i==3){
                break;
            }
        }
        System.out.println("========================");
        /**
         * 准备写5天日记,第三天忘了,之后继续
         */
        for (int i = 1; i < 6; i++) {
            if (i==3){
                continue;
            }
            System.out.println("第"+i+"天日记");
        }

6.随机数Random类

  • Random生成随机数特点:
    • random.nextInt(n);生成一个0到n-1的随机数
  • Random生成区间随机数技巧:
    • 减加法:random.nextInt(10)+1;生成1-10
/**
 * 猜字游戏
 */
public class RandomDemo1 {
    public static void main(String[] args) {
        Random random = new Random();
        Scanner scanner = new Scanner(System.in);
        //random.nextInt(n);生成一个0到n-1的随机数
        int i = random.nextInt(100)+1;
        System.out.println(i);
        while (true){
            System.out.println("请输入1-100间的数字:");
            int s = scanner.nextInt();
            if (s<0||s>100){
                System.out.println("请输入1-100范围的数字");
            }else if (s==i){
                System.out.println("恭喜你猜中了");
                break;
            }else if (s<i){
                System.out.println("猜的数略小");
            }else if (s>i){
                System.out.println("猜的数略大");
            }else {
                System.out.println("请输入正确的数字");
            }
        }
    }
}

RecordDate:2021/08/07

六、数组

1.数组概述

1.1数组是什么?

数组是用来存储一批同种类型数据的内存区域(容器)

1.2示例

        int[] arr={21,58,698,88};

        String[] names={"张三","lisi","王wu"};

1.3关键点

  • 定义数组存储数据;
  • 操作数组元素;
  • 解决问题;
  • 数组内存原理
  • 数组使用注意点

2.数组定义方式

2.1静态初始化数组

定义数组时直接赋值:

数据类型[] 数组名 = new 数组数据类型[]{元素1,元素2}
int[] ages = new int[]{15,24,28};

//简化格式
数据类型[] 数组名 ={元素1,元素2}
int[] ages = {15,24,28};

 /**
         * 静态初始化数组
         */
        double[] money = new double[]{15.6,65.3,99.9};
        double[] money2 ={15.6,65.3,99.9};

        int[] ages = new int[]{5,6,5,6};
        int[] ages2 = {5,6,5,6};

        String[] names = new String[]{"张三","lisi","王wu"};
        String[] names2 = {"张三","lisi","王wu"};

2.2 数组基本原理

  • 内存中开辟数组变量区域ages;
  • new出来对象存储信息,是一片连续区域,地址给变量名
  • 引用类型里面存地址;基本类型里面存数据
[I@4c873330[I@4c873330
示例解释代表数组代表int型表示地址,后接十六进制首地址

数组的基本原理.png

2.3 数组访问

  • 数组访问
    • 数组名[索引]
    • 数组长度属性:length
    • 数组最大索引:length-1;元素最少有一个,索引位0
  • 注意事项
    • 数据类型[] 数组名 也可以是 数据类型 数组名[]
    • 数组存放数据类型固定
    • 数组一旦定义,程序执行过程中,长度、类型固定

2.4 动态初始化数组

  • 定义数组时,只确定元素类型和长度,之后存值

  • 格式:

int[] sums= new int[9];
  • 原理:

    • 类似静态初始化,变量名存入首地址,长度确定,每个地址存入默认值,如:int型默认存0;引用类型null
  • 静动两者使用场景区别:

    • 静态,知道具体值;
    • 动态,知道数据量,不知道具体值
  • 静动分开使用

元素默认值规则.png

3.数组遍历

3.1求和 求最大值

 int[] arr={21,58,698,88};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        //求和
        int sum=0;
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        System.out.println(sum);

        //求最大值
        //建议用第一个元素作为参照
        int Max=arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (Max<arr[i]){
                Max = arr[i];
            }
        }
        System.out.println("最大值:"+Max);

3.2猜字游戏

public class ArrayDemo2 {
    public static void main(String[] args) {
        /**
         * 猜字游戏:
         *      随机生成1-20间5个数(不论是否重复)
         *      猜字:输出第一次出现该树的位置,全部输出结束
         */

        Random random = new Random();
        int[] Numbers = new int[5];
        int count = 0;
        for (int i = 0; i < 5; i++) {
            Numbers[i] = random.nextInt(20)+1;
        }
//        System.out.println(Arrays.toString(Numbers));
        Scanner scanner = new Scanner(System.in);
        OUT:
        while (count<5){
            boolean a = false;
            System.out.println("请输入1-20的数字");
            int test = scanner.nextInt();
            if (test<0 || test>20){
                System.out.println("数字范围输入错误");
                continue ;
            }
            for (int i = 0; i < 5; i++) {
                if (Numbers[i] == test){
                    System.out.println("运气不错,猜中了,数字"+Numbers[i]+"第一次出现在"+i+"位置");
                    Numbers[i]=99;
                    count++;
                    System.out.println("还差"+(5-count)+"个,就都猜中了!");
                    a=true;
                    //break OUT;//结束了整个循环,游戏结束
                }
            }
            if (!a){
                System.out.println("没猜中,再来一次吧");
            }
        }
        System.out.println("恭喜,猜中全部数字,本局结束。");
    }
}

3.3 随机排名

 /**
         * 随机排位:
         *      录入五个人,给他们随机排序
         */

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要给几个人排序");
        int length=scanner.nextInt();
        int[] users = new int[length];
        int count = 0;
        for (int i = 0; i < users.length; i++) {
            System.out.println("请输入第"+i+"个人的ID");
            users[i]=scanner.nextInt();
        }
        Random random = new Random();
        for (int i = 0; i < users.length; i++) {
            int temp=random.nextInt(users.length);
            int tempUser = users[0];
            users[0]=users[temp];
            users[temp]=tempUser;
        }
        System.out.println(Arrays.toString(users));

4.数组排序

  • 数组排序
    • 对数组中元素,按从小到大或从大到小排序
  • 排序技术
    • 冒泡排序
    • 选择排序
    • 快速
    • 插入
  • 数组搜索相关技术
    • 二分搜素
    • 分块查找
    • 哈希表查找

4.1 冒泡排序:

  1. 思想:
    1. 从头开始,两两排序,大小互换
    2. 每轮把当前数组最大元素,存到数组末尾
  2. 实现步骤:
    1. 外部循环轮次(数组长度-1)
    2. 内部循环轮次,每轮次依次往后比较几个位置(数组长度-i-1)
    3. 前大于后,二者交换
/**
         * 冒泡排序
         */
        int[] arr={6,8,7,3};
        //定义控制循环比较轮次
        for (int i = 0; i < arr.length-1; i++) {
            //0轮,比较3次,j=0 1 2
            //1轮,比较2次,j=0 1
            //2轮,比较1次,j=0
            for (int j = 0; j < arr.length-i-1 ; j++) {
               if (arr[j]>arr[j+1]){
                   int temp = arr[j+1];
                   arr[j+1]=arr[j];
                   arr[j]=temp;
               }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println(Arrays.toString(arr));

5.数组的内存图

5.1 Java内存分配

  • 栈(数据方法短暂地运行区域)
    • 栈内存:方法运行时进入的内存;变量也在这里
  • 堆(数据停留较长时间的区域)
    • new出来东西,在此内存开辟空间并产生地址
    • 空间大,将new出大量数据存入
  • 方法区
    • 字节码文件加载时进入的内存
  • 本地方法栈
  • 寄存器

5.2 Java内存分配流程:

  1. 编译后运行,到main方法,放入方法区;
  2. 方法,开辟栈内存空间,基本数据类型存入值,引用类型存入变量名;
  3. new在栈内存中开辟空间,生成地址,存入数值,;
  4. 根据从右向左运行的原理,将new生成的地址赋给变量;
  5. 根据地址和空间内索引,赋值;

Java内存分配流程.png

5.3两个变量指向同一数组

原理同上;将arr的地址赋给arr2;

        /**
         * 两个变量指向同一数组
         */
        int[] arr={6,8,7,3};
        int[] arr2=arr;
        System.out.println(arr);//[I@1b6d3586
        System.out.println(arr2);//[I@1b6d3586

        arr2[0]=1;
        System.out.println(arr[0]);//1

6.数组使用常见问题

问题释义原因
ArrayIndexOutOfBoundsException数组索引越界异常访问元素位置超过最大索引
NullPointerException空指针异常数组变量中没存地址,null,访问

RecordDate:2021/08/07

七、方法

1.方法概述

方法一种语法结构,把一段代码封装成一个功能,方便重复使用;
好处:提高代码复用性;
让程序逻辑更清晰;

2.方法定义格式

完整格式:

修饰符 返回值类型 方法名(形参列表){

​	方法体代码(需要执行的功能代码)

​	return 返回值;

}

2.1 方法常见问题

  • 编写顺序无所谓;
  • 方法间是平级,不能嵌套定义;
  • void,无需return;其他设置类型需return相应类型;
  • 方法不调用,不执行,严格匹配参数情况;
  • 有返回值的方法,调用可以选择定义变量接收结果;

2.2 求和

/**
     * 计算1-n的和
     * @param n
     * @return
     */
    public static int sum(int n){
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum+=i;
        }
        return sum;
    }

2.3 判断奇数偶数

/**
     * 判断是奇数还是偶数
     * @param n
     * @return
     */
    public static int X(int n){
        int x;
        if (n%2==0){
            x=2;
            System.out.println(n+"是偶数");
        }else {
            x=1;
            System.out.println(n+"是偶数");
        }
        return x;
    }

2.4 求最值

/**
     * 求数组最大值
     * @param array
     * @return
     */
    public static int MaxArray(int[] array){
        int max = array[0];
        for (int i = 1; i <array.length ; i++) {
            if (max<array[i]){
                max = array[i];
            }
        }
        return max;
    }

3.方法的内存原理

3.1 方法的调用流程,内存图解

  • 方法,没有被调用的时候,在方法区的字节码文件中存放;
  • 方法,被调用时候,需要进入到栈内存中运行;
  1. 方法不调用时,存放在方法区;
  2. 方法main运行时,在栈内存开辟空间;
  3. 再调用add方法,再开辟空间,将传入值存在开辟的空间;
  4. 方法使用结束,从栈内存退栈;

方法调用内存图解.png

4.方法的参数传递机制

4.1基本类型传递机制

  • Java参数传递机制:值传递(不同方法内,只是数值相同);
  • 注意:
实参:方法内部定义变量
形参:定义方法时,()中所声明的参数
    /**
     *    基本类型,值传递
     */
    public static void main(String[] args) {
        int a=10;
        chang(a);
        System.out.println(a);//10
    }
    public static int chang(int a){
        System.out.println(a);//10
        a=50;
        System.out.println(a);//50
        return a;
    }

4.2 引用类型传递

引用类型:传递地址,修改地址空间内的数据;

    /**
     *    引用类型,地址传递
     */
    public static void main(String[] args) {
        int[] a={10,2,6};
        chang(a);
        System.out.println(a[0]);//50
    }
    public static void chang(int[] a){
        System.out.println(a[0]);//10
        a[0]=50;
        System.out.println(a[0]);//50
    }

4.3 打印整形数组内容

 /**
     *    引用类型,地址传递
     */
    public static void main(String[] args) {
        int[] a={10,2,6};
        print(a);
    }
    public static void print(int[] a){
        if (a!=null && a.length>0){
            System.out.println("该数组内容为:"+ Arrays.toString(a));
        }
    }

4.4 数组中查询指定元素的索引

/**
     *    数组中查询指定元素的索引
     */
    public static void main(String[] args) {
        int[] a={10,2,6};
        int b = 10;
        System.out.println(select(a, b));
    }
    public static int select(int[] a,int b){
        if (a!=null && a.length>0){
            for (int i = 0; i < a.length; i++) {
                if (a[i] == b){
                    return i;
                }
            }
        }
        return -1;
    }

4.5 比较任意两个数组是否一样

/**
     * 比较任意两个数组是否一样
     */
    public static void main(String[] args) {
        int[] a={10,2,6};
        int[] b={10,2,6};
        if (compare(a,b)){
            System.out.println("两个数组相等");
        }else {
            System.out.println("两个数组不等");
        }
    }
    public static boolean compare(int[] a,int[] b){
        if (a.length != b.length){
            return false;
        }

        for (int i = 0; i < a.length; i++) {
            if (a[i] != b[i]){
                return false;
                }
            }
        return true;
    }

5.方法重载

  • 方法重载:

    • 同一个类中,多个名称相同,但形参列表不同,形参类型不同,这些方法就是方法重载;
  • 重载识别技巧:

    • 同一个类,方法名称相同,形参列表不同,就是重载(无关修饰符,返回值类型)

    • 形参列表不同:形参个数,类型、顺序不同,不关心形参名称

       /**
           * 方法重载
           * @param args
           */
          public static void main(String[] args) {
              fire();
              fire("老A");
              fire("老A",666);
              Integer a = 666;
              System.out.println("嗨嗨"+fire("老A",a));
          }
          public static void fire(){
              fire("老E");
          }
      
          public static void fire(String location){
              fire(location,1);
          }
      
          public static void fire(String location,int number){
              System.out.println("给"+location+"的老铁送"+number+"个大火箭!");
          }
      
          //无法以返回值类型区分,可以以形参类型区分
          public static int fire(String location,Integer number){
              System.out.println("给"+location+"的老铁送"+number+"个大火箭!");
              return 666;
          }
      

6.单独使用return关键字

关键字作用
return:可以立即跳出并结束当前方法的执行
break:跳出并结束当前所在的循环
continue:跳过当次循环,进入下一次;

RecordDate:2021/08/08

八、面向对象

1.面向对象概述

  • 更加符合现实生活;
  • 面对问题,寻找合适的工具,调用合理的方法,解决问题;
  • 复杂问题,梳理流程,组合工具和使用方法,灵活应对复杂局面,更具拓展性和维护性;
  • 没有合适的工具,就自己设计,自己用;
  • 自己设计的工具,足够范用,足够安全稳定,可以开源给别人用;

2.设计对象及注意事项

描述
类(设计图):对象共同特征的描述;
对象:真实存在的具体实例;
结论:java中,必须先设计类,才能创建对象并使用

2.1类注意事项:

首字母大写,满足驼峰式;

一个java文件可以定义多个class,只可以有一个public修饰,且必须是用来修饰文件名;

3.内存机制

3.1两个对象内存图

  1. 运行Test.class,main方法存入方法区,在栈内存开辟main方法空间;
  2. 执行第一行,创建变量Car c1 存入栈内存;
  3. 执行new Car(),在堆内存中开辟对象空间,对象属性值为默认,最后存入成员方法引用地址(指向方法区方法);
  4. 将空间地址赋给变量c1
  5. 根据c1地址和属性索引给c1赋值(原理同数组赋值类似);
  6. c1.start()c1通过地址找到对象,再找到成员方法引用地址,找到start方法,start()方法提取到栈内存运行;
  7. 由于start()方法是通过c1路径调用,内部属性值访问c1

两个对象的内存图.png

3.2 两个对象指向同一个内存图

  1. 基本原理与上方相同;
  2. 将s1地址赋给s2,s2修改了堆内存中数据,s1和s2输出值都变化;
Student s = new Student();
s.name="英语龙";
Student s1 = s;
s1.name = "三角箭";

3.3 垃圾回收装置

当堆内存中对象,没有被任何变量引用(指向)时,就会被判定为内存中垃圾;

Java存在自动垃圾回收器,会定期清理;

4.构造器

4.1 构造器作用

  • 定义在类中,可以用于初始化一个类的对象,并返回对象地址;
  • new Car();中的Car()便是构造器

4.2 构造器格式

修饰符 类名(){

//无参构造器

}

修饰符 类名(形参列表){

//有参构造器

}

    public Car(String name, double price) {
        this.name = name;
        this.price = price;
        System.out.println("有参构造器被调用");
    }

    public Car() {
        System.out.println("无参构造器被调用");
    }

4.3调用构造器得到对象格式

类 变量名 = new 构造器;
Car c = new Car();
Car car1 = new Car("胜利冲锋", 19.9);

4.4 构造器的分类和作用

构造器表现注意
无参构造器(默认存在):初始化对象时,成员变量数据均采用默认值;一旦有参构造器创建;再用无参构造器需要自行创建
有参构造器:初始化对象时,同时可以接收参数为对象赋值;

4.5 this关键词,代表当前对象地址

可以出现在构造器中,方法中;

4.6 this关键字作用

可以用于指定访问当前对象的成员变量、方法;

    public Car(String name, double price) {
        this.name = name;
        this.price = price;
        System.out.println("有参构造器被调用");
    }


    public void goWith(String name) {
        System.out.println(this.name+"和"+name+"比赛!");
    }
	Car car = new Car();
    car.name = "旋风冲锋";
    car.goWith("飓风音速");
    //旋风冲锋和飓风音速比赛!

5.封装

  • 面向对象三大特征:封装、继承、多态
  • 封装:如何正确设计对象的属性和方法;解决属性和方法属于哪个对象问题;
    • **封装原则:**对象代表什么,就得封装对应数据,并提供数据对应的行为;
    • 基本思想:决定属性和行为的归属问题,行为是用来处理对应属性的;人吃饭睡觉;门开关;票地址价格买票

5.1 进行更好的封装

  • 对成员变量使用private(私有隐藏)关键字修饰
    • private修饰成员只能在当前类中访问;
  • 为每个成员提供配套的public修饰的getter和setter方法,
    • 方便取值和赋值
public class Student {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>0 && age<200){
            this.age = age;
        }else {
            System.out.println("不符合符合规范");
        }
    }
}


        Student s = new Student();
        s.setAge(-99);
        System.out.println(s.getAge());
        s.setAge(99);
        System.out.println(s.getAge());


不符合符合规范
0
99

5.2 特征的含义

所谓特征,指java的基本特点,即使毫无意义,通常也要满足这样的设计要求来编写;

6.标准 JavaBean

JavaBean:实体类,其对象用于在程序中封装数据;

6.1成员变量和局部变量区别

区别成员变量局部变量
类中位置类中,方法外常见方法内
初始化值有默认值,无需初始化需初始化
内存位置
生命周期随对象创建存在,随对象消失随方法存在
作用域所归属的大括号内

javaBean对象内存图.png

RecordDate:2021/08/09

九、API

  • API(ApplicationProgrammingInterface,应用程序编程接口)
  • java写好的功能代码,可直接调用
  • 有相应的技术文档

十、String类型

​ 定义的变量用于存储字符串,同时提供了很多操作字符串的功能;

1 String类特点

  • String常被称为不可变字符串类型,对象创建后不可更改;
  • String每次修改都是产生并指向新的字符串对象;
  • 通过“+”连接几个字符串,原来字符串没有改变,只是可以通过拼接控制输出效果

2 创建字符串对象

/**
 * 创建String的常用方法
 */
public class StringDemo {
    public static void main(String[] args) {
        String name = "wind";
        System.out.println(name);

        String s1 = new String();
        System.out.println(s1);//空白

        String s2 = new String("岩峰");
        System.out.println(s2);

        char[] c = {'a','v','i'};
        String s3 = new String(c);
        System.out.println(s3);//avi

        byte[] b ={97,98,99};
        String s4 = new String(b);
        System.out.println(s4);//abc
    }
}

3 方法间区别

以“ ”方式给出字符串对象,在字符串常量池中存储,相同内容只存一份

new对象,产生新对象,放在堆内存中;

        String name = "wind";
        String name2 = "wind";
        System.out.println(name==name2);//true

        char[] c = {'a','v','i'};
        String s3 = new String(c);
        String s33 = new String(c);
        System.out.println(s3==s33);//false

3.1 String常量原理

  • 在堆内存的字符串常量池创建,将地址赋给变量名;
  • 相同内容不会在常量池中创建新的;

字符串常量内存原理.png

3.2 new String对象原理

每次new都会在堆内存中创建新的对象,赋予常量的地址不同;

new字符串对象内存原理.png

new

4 常见面试题

        String s2 = new String("wind");//创建两个对象;一个常量,一个new;指向堆内存
        String s22 = "wind";//创建0个对象,原因是常量池中有wind了,上方创建,指向常量池
        System.out.println(s2==s22);//false

        String s1 = "abc";//常量池
        String s2 = "ab";
        String s3 = s2 + "c";//运算,指向堆内存
        System.out.println(s1==s3);//false

        String s1 = "abc";//常量池
        String s2 = "a"+"b"+"c";//java存在编译优化机制,直接转成"abc";字面量是确定的会优化
		//变量编译阶段不知道值,字面量可以
        System.out.println(s1==s2);//true

5 String类型常用API

        //自定义一个字符串
        //注意这里字符串最后是空,下面会用到
        String str = new String("13,2df+fk,05s,kd, ");

        //这里我们假设使用","作为分隔符
        String[] newStr = str.split(",");
        //[13, 2df+fk, 05s, kd,  ]
        System.out.println(Arrays.toString(newStr));
        
        //两个分隔符的情况  ","和"+"作为分隔符
        //同样还是返回字符串数组类型的数据
        //这里我实验之后发现给"+"加上"[]"之后才可以通过编译,得到正确的结果
        String[] newStr2 = str.split(",|[+]");
        //[13, 2df, fk, 05s, kd,  ]
        System.out.println(Arrays.toString(newStr2));
————————————————
        String name = "wind";
        String passWord = "qq123456";
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入姓名:");
        String name1 = scanner.next();
        System.out.println("输入密码:");
        String pass = scanner.next();
        /**
         * equals 比较字符串是否一致
         */
        if (name.equals(name1) && passWord.equals(pass)){
            System.out.println("正确!");
        }else {
            System.out.println("错误!");
        }

        String nameTwo = "WinD";
        String passTwo= "Qq123456";
        /**
         * equalsIgnoreCase  忽略大小写,比较字符串是否一致
         */
        if (name.equalsIgnoreCase(nameTwo) && passWord.equalsIgnoreCase(passTwo)){
            System.out.println("正确");
        }

String常用API.png

5.1 验证码


/**
 * 验证码:
 */
public class StringTest1 {
    public static void main(String[] args) {
        String datas = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        int dataLength = datas.length();
        Random random = new Random();
        String code = "";
        for (int i = 0; i < 5; i++) {
            int index = random.nextInt(dataLength);
            char c = datas.charAt(index);
            code += c;
        }
        System.out.println("输出字符串:"+code);
    }

}

5.2 屏蔽手机号

/**
 * 屏蔽部分手机号码
 */
public class StringTest2 {
    public static void main(String[] args) {
        String phone = "132xxxx9xxx";

        //截取前三位
        String before = phone.substring(0,3);
        //截取后四位
        String after = phone.substring(7);

        String phone2 = before+"****"+after;
        System.out.println(phone2);
    }
}

十一、ArrayList

  • 代表集合类,集合是一种容器,与数组类似,不同的是集合大小不固定;
    • 非常适合元素个数不确定,进行增删业务场景
    • 功能丰富
  • 通过创建ArrayList对象得到一个集合容器;
    • ArrayList是集合一种,支持索引
        ArrayList list = new ArrayList();
        list.add(1);
        list.add("张燕");
        list.add("凛冬");
        list.add(188);
        list.add(1999);
        //[1, 张燕, 凛冬, 188, 1999]
        System.out.println(list);

        //指定位置插入,后面后移
        list.add(2,"小火火");
        //[1, 张燕, 小火火, 凛冬, 188, 1999]
        System.out.println(list);

1. 泛型概述

ArrayList泛型类,编译阶段约束集合对象只能操作某种数据类型;
ArrayList只能操作字符串类型;
ArrayList只能操作整数类型;
注意:集合中只能存储引用类型,不支持基本数据类型

2.集合案例

2.1 遍历并删除元素值

删除两种方案:

1.应对补位,i--;

2.倒序删除;

/**
 * 遍历并删除元素值:
 *      低于80的值删除;
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        Integer[] list = {98,77,66, 89,79,50,88,100};
        ArrayList<Integer> scores = new ArrayList<>();
        //同<泛型>添加
        Collections.addAll(scores, list);

        //方案一:i--补位
/*        for (int i = 0; i < scores.size(); i++) {
            if (scores.get(i) < 80){
                scores.remove(i);
                i--;//删除成功后,后退一步,再次判断,应对补位
            }
        }*/

        //方案二:倒排,删除后补位不影响
        for (int i = scores.size()-1; i >0 ; i--) {
            if (scores.get(i) < 80){
                scores.remove(i);
            }
        }
        System.out.println(scores.toString());
    }
}

2.2 存储自定义型对象:

集合中存储的是对象的地址!

/**
 * 存储自定义型对象:
 *  存入三部电影信息,并输出
 */
public class ArrayListDemo2 {
    public static void main(String[] args) {
        Movie m1 = new Movie("斗破苍穹",6.6,"消炎");
        Movie m2 = new Movie("武动乾坤",6.6,"林东");
        Movie m3 = new Movie("大主宰",7.6,"木木");

        ArrayList<Movie> movies = new ArrayList<>();
        //存了三个地址
        movies.add(m1);
        movies.add(m2);
        movies.add(m3);
        for (int i = 0; i < movies.size(); i++) {
            Movie movie = movies.get(i);
            System.out.println(movie.getName()+movie.getScore()+movie.getActor());
            System.out.println("----------------------------");
        }
    }
}

2.3 元素搜索

/**
 * 元素搜索:
 */
public class ArrayListDemo3 {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        students.add(new Student("1","赵日天",18,"炸天一班"));
        students.add(new Student("2","叶良辰",38,"炸天一班"));
        students.add(new Student("3","荀彧",88,"炸天二班"));
        students.add(new Student("4","李白",28,"炸天二班"));

        System.out.println("全部学生信息");
        System.out.println("-------------------------");
        for (int i = 0; i < students.size(); i++) {
            Student s = students.get(i);
            System.out.println(s.getStudyNumber()+"\t"+s.getName()+"\t"+s.getAge()+"\t"+s.getClassName());
            System.out.println("-------------------------");
        }

        Scanner scanner = new Scanner(System.in);

        while (true){
            System.out.println("输入要搜索学生信息的Id:");
            String id = scanner.next();
            //根据学号搜索信息
            Student ss = getStudentById(students, id);
            if (ss==null || ss.equals("")){
                System.out.println("查无此人");
                System.out.println("-------------------------");
            }else {
                System.out.println("-------查询到的信息如下--------");
                System.out.println(ss.getStudyNumber()+"\t"+ss.getName()+"\t"+ss.getAge()+"\t"+ss.getClassName());
                System.out.println("-------------------------");
            }

        }

    }

    /**
     * 根据学号查询信息:
     * @param students 全体学生信息集合
     * @param id
     */
    private static Student getStudentById(ArrayList<Student> students,String id) {
        for (int i = 0; i < students.size(); i++) {
            Student student = students.get(i);
            if (student.getStudyNumber().equals(id)){
                return student;
            }
        }
        return null;
    }
}

RecordDate:2021/08/10