Java基础学习

参考资料

视频教程:https://www.bilibili.com/video/BV12J41137hu/?p=31&spm_id_from=pageDriver&vd_source=73cf57eb7e9ae1ddd81e6b44cf95dbeb

参考笔记1:https://www.kuangstudy.com/bbs/1486242169726898178#header23

参考笔记2:https://www.kuangstudy.com/bbs/1464859409422233602#header5

java常识

Java的诞生路线

  • C语言接近汇编,很快,很高效,但是并不完全跨平台,而且很容易出错而药等程序运行才能发现。并且操控内存,指针那些比较复杂。所以诞生了C++
  • C++的游戏这方面做的很好,但是对比C复杂很多,不易入门。并且还是有一些繁琐。这个时候Java应运而生。
  • Java,最开始想叫C++--,就是保留了C++的部分优势,又删掉了一些复杂的东西。后来还是起名叫java了。

Java特性和优势

  • 简单性

  • 面向对象

  • 可移植性

    Write Once, Run Anywhere

  • 高性能

  • 分布式

  • 动态性

  • 多线程

  • 安全性

  • 健壮性

Java三大版本

JavaSE:标准版(桌面程序,控制台开发......)
JavaME:嵌入式开发 (手机,小家电....)
JavaEE: E企业级开发(web端,服务器开发...)

JDK,JRE,JVM

JDK: Java Development Kit

  • jdk是java开发环境,包括了JRE,而JRE又包括了JVM。而jdk在jre的基础上又加了一些工具

JRE: Java Runtime Environment

  • java运行时环境。只要装了jre就可以运行java程序了。而真实情况下安装了JDK就可以了,因为jdk包含jre呀

JVM : JAVA Virtual Machine

  • java虚拟机(相当于在所有的系统上装了一个java的cpu)

1671539333617

java开发环境搭建

  • 卸载JDK
    1.删除Java的安装目录
    2.删除JAVA_HOME
    3.删除path下关于Java的目录
    4.java -version
  • 安装JDK

1.百度搜索JDK8,找到下载地址
2.同意协议
3.下载电脑对应的版本
4.双击安装JDK
5.记住安装的路径

  1. 配置环境变量
    1.我的电脑-->右键->属性
    2.环境变量-->JAVA_HOME
    3.配置path变量
  2. 测试JDK是否安装成功
    1.打开cmd
    2.java -version

JDK文件夹中的相关文件

(1)bin
存放Javac.exe(Java编译器);Java.exe(Java运行程序);jar.exe(打包工具);Javadoc.exe(文档生成工具)等可执行文件。
(2)db
小型数据库,学习JDBC的时候不需要再安装数据库软件。
(3)include
JDK由于是用C和C++实现的,这里存放了需要引入的C语言的头文件。
(4)jre
Java运行环境目录,包含了JVM(Java虚拟机);运行时的类包;Java启动器以及一个bin目录,但不包括开发环境中的开发工具。
(5)lib
library的缩写,意为Java类库或库文件,是开发工具使用的归档包。
(6)Javafx-src.zip
存放Java FX(Java图形用户界面工具)的源代码。
(7)src.zip
存放JDK的核心源代码。
(8)Javac.exe和Java.exe的区别
①Javac.exe是Java编译器,Java源文件为 .java,此工具将源文件编译为 .class 文件。
②Java.exe负责运行Javac.exe编译后生成的*.class文件。

第一个java程序Hello.java

public class Hello {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

Java程序运行机制

  • 编译型 -已经解释完成
  • 解释型 -边执行边解释

程序运行机制

image-20211028161026456

java基础语法

注释

1)单行注释
//这是单行注释
2)多行注释
    /*
     * 这是多行注释 
     * 这是多行注释 
     * 这是多行注释
     *  ……
     */
3)JavaDoc文档注释
/** 文档注释 */

关键字

1673270497470

标识符

1673270261013

数据类型

  • 知识点

1673271278034

  • 例子(long类型一定要加大写L,养成好习惯!小写l容易看成1)

1673271086789

什么是字节?

1673271572081

数据类型扩展

  • 整数扩展

进制

二进制0b
十进制
八进制0
十六进制0x

1673272727694

  • 浮点数扩展

1673272988675

  • 字符扩展

1673273779687

1673273075021

  • 转义字符(制表符,换行符)和new 开辟新的地址空间

    \r的话就是,将光标定位到当前行首

1673273330341

  • 布尔值扩展

1673273420689

这两种是一样的

类型转换

1673273984199

案例

  • 强制转换(字符串不能用这种方式强转为int,因为,String不属于基本数据类型,而属于引用数据类型)

1673274096491

  • 自动转换

1673274146036

注意点

1673274175592

案例

1673274255863

字符(强制与自动案例)

1673274324691

操作较大数的时候注意溢出问题

JDK7新特性,数字之间可以用下划线分割

1673274522047

变量、常量、作用域

变量

1673278245590

1673278280670

变量作用域

1673278343756

  • 实例变量和局部变量

1673278532876

  • 类变量(从属于类,不需要创建对象就可以用)
变量的默认值
布尔值为 false
int 为 0
String 为 null
除了基本类型,其余的默认值都是null

1673278670640

当我去掉了,static(报错)

1673278694788

常量

1673278843233

1673278947569

变量的命名规范

1673279045793

运算符

  • %为取余,也叫做模运算

1673279202668

  • 解释
运算符 运算 范例 结果 说明
+ 正号 a=3;+a 3 算数运算符
- 负号 b=4;-b -4 算数运算符
+ 5+5 10 算数运算符
- 6-4 2 算数运算符
* 3*4 12 算数运算符
/ 除(整除的结果) 7/5 1 算数运算符
% 取模(求余数) 7%5 2 算数运算符
++ 自增(前) a=2;b=++a a=3;b=3 算数运算符
++ 自增(后) a=2;b=a++ a=3;b=2 算数运算符
自减(前) a=2;b=—a a=1;b=1 算数运算符
自减(后) a-2;b=a— a=1;b=2 算数运算符
= 赋值 a=2 把2赋值给a 赋值运算符
> 大于 关系运算符
< 小于 关系运算符
>= 大于等于 关系运算符
<= 小于等于 关系运算符
== 等于 关系运算符
!= 不等于 关系运算符
&& 逻辑运算符
\ \ 逻辑运算符
! 非(取反) 逻辑运算符
& 位运算符
\ 位运算符
^ 非(取反) 位运算符
~ 取反 位运算符
>> 右移 将底数/2 位运算符
<< 左移 将底数*2 位运算符
>>> 位运算符
?: 偷懒 条件运算符
+= 偷懒 a=2;b=2; a+=b;其实是a=a+b 扩展赋值运算符
-= 偷懒 a=2;b=2; a-=b;其实是a=a-b 扩展赋值运算符
*= 偷懒 a=2;b=2; a=b;其实是a=ab 扩展赋值运算符
/= 偷懒 a=2;b=2; a/=b;其实是a=a/b 扩展赋值运算符

算术运算符
赋值运算符
关系运算符

1673279409247

  • 小细节

按照容量优先级自动转换

一堆类型,有long的,输出的一定是long

有int的一定是int

这几个double的一定是double

1673279514226

  • 关系运算符返回结果

1673279810839

  • 扩展赋值运算符

1673281165724

++与--

1673280094071

扩展 :幂运算,(算平方,与次方),这里是3的2次方,等于9

1673280173112

逻辑运算符与短路运算

1673280479299

位运算符

1673280974227

字符串连接符(字符串拼接符)

1673281125717

三元运算符

1673281336449

运算符优先级

1673281717753

包机制

包的本质就是文件夹

1673282044717

.*为通配符

1673282275868

Javadoc生成文档

1673282863507

  • 自己生成帮助文档

(1)参数
①@author 作者名
②@version 版本号
③@since 指明需要最早使用的JDK版本
④@param 参数名
⑤@return 返回值情况
⑥@throws 异常抛出情况

(2)举例

package com.lovi.base.learn;

/**
 * @author Lovi
 * @version 1.0
 * @since 1.8
 */
public class JavaDoc {
    /**
     * 
     * @param a
     * @return
     * @throws Exception
     */
    public String test(String a)throws Exception{
        return null;
    }
}

生成文档的方法

  • 命令行
生成命令:javadoc 参数 **.java
①先到该文件的目录,然后导航栏加上cmd进入doc窗口
②输入javadoc -encoding UTF-8 -charset UTF-8 **.java
③也可以使用IDE来生成,以eclipse和idea为例

过程

1673284023001

双击index.html

1673284093074

生成啦

1673284153825

  • idea
Tools→Generate JavaDoc

一不小心把全部都给生成了

zh_CN
-encoding utf-8 -charset utf-8

1673284674537

成功啦,(只打开我要生成的)

1673284928363

1673284861311

  • 还可以这样

1673285238454

这样

1673285293527

Java流程控制

用户交互Scanner(输入!!)

1673326608614

例子

  • 用next()
package com.lovi.base.learn.scanner;

import java.util.Scanner;


public class Demo1 {
    public static void main(String[] args) {
        //新建一个scanner对象
        Scanner scanner = new Scanner(System.in);
        System.out.println("用next()的方式接收字符串...");
        //判断用户是否还有输入(如果有就执行if,里边的)
        if(scanner.hasNext()){
            String str1 = scanner.next();
            System.out.println("next()==>"+str1);
        }
        //IO流的类用完都要关闭,否则会一直占用资源,养成好习惯。
        scanner.close();


    }
}

发现只输出了hello

1673328191126

  • 用nextLine
package com.lovi.base.learn.scanner;

import java.util.Scanner;

public class Demo2 {
    public static void main(String[] args) {
        //新建一个scanner对象
        Scanner scanner2 = new Scanner(System.in);
        System.out.println("用nextLine()的方式接收字符串...");
        //判断用户是否还有输入(如果有就执行if,里边的)
        if(scanner2.hasNextLine()){
            String str2 = scanner2.nextLine();
            System.out.println("nextLine()==>"+str2);
        }
        //IO流的类用完都要关闭,否则会一直占用资源,养成好习惯。
        scanner2.close();
    }
}

1673328180654

探索到知识点

1673326839201

简单的方式

package com.lovi.base.learn.scanner;

import java.util.Scanner;

public class Demo3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入数据");
        String str = scanner.nextLine();
        System.out.println("输入的数据为==》"+str);

    }

}

1673327813491

用scanner判断整数和小数

package com.lovi.base.learn.scanner;

import java.util.Scanner;

public class Demo4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int i = 0;
        float f = 0.0f;
        System.out.println("请输入整数...");
        if(scanner.hasNextInt()){
            i = scanner.nextInt();
            System.out.println("输入的整数为:"+i);
        }else {
            System.out.println("输入的不是整数!!!");
        }

        //=================

        System.out.println("请输入小数...");
        if(scanner.hasNextFloat()){
            f = scanner.nextFloat();
            System.out.println("输入的小数为:"+f);
        }else {
            System.out.println("输入的不是小数!!!");
        }

        scanner.close();
    }
}

1673328626829

如果输错

1673328659546

1673328840709

(发现,这种缺点是,这个整数会自动转换成浮点型)

低精度往高精度自动转换

说白了,就是粗往细自动转换!

sanner 计算一堆输入数据的平均值,和总和

package com.lovi.base.learn.scanner;

import java.util.Scanner;

public class Demo5 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入数据,我们会计算出,数据的总和和平均值");

        double x = 0;//输入的数据
        int m =0;//数据的个数
        double sum = 0;//数据的总和
        //只要用户有输入就执行这个循环
        while (scanner.hasNextDouble()){
            x = scanner.nextDouble();
            m++;//个数+1
            sum = sum + x;//计算总和,把每次的x都给加进去
            System.out.println("当前输入了第"+m+"个数据,总和为:"+sum);

        }
        System.out.println("数据总和为:"+sum);
        System.out.println("数据平均值为:"+sum/m);
    }
}

1673329607046

顺序结构

1673331520725

1673331562093

选择结构

if 选择结构

  • if单选择结构

1673331805160

判断字符串是否相等!==》 字符串a.equals("字符串b");

  • if双选择结构

1673332093939

  • if多选择结构

1673332307649

  • 嵌套的if结构

1673332437286

switch 多选择结构

1673332474091

1673332659648

switch的表达式也可以是字符串

1673332725837

扩展原理

1673332880642

循环结构

1673332974226

while 循环

1673333038982

1673333127213

1673333306742

do...while 循环

1673333380419

1673333550869

  • while 与do...while区别

1673333635574

for循环

1673333698071

1673333905247

for的死循环

1673333947533

练习1:计算0到100之间的奇数和偶数的和

1673334222357

练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个

package com.lovi.base.learn;

public class ForDemo1 {
    public static void main(String[] args) {
        //用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个

        for(int i = 1;i<=1000;i++){
            //算出能被5整除的数
            if(i%5==0){
                //不换行
                System.out.print(i+"\t");
            }
            //每行输出3个
            if(i%(5*3)==0){
                //换行
                System.out.println();
            }
            //println 输出完会换行
            //print 输出完不会换行

        }
    }
}

1673334719472

练习3:打印九九乘法表

package com.lovi.base.learn;

public class ForDemo2 {
    public static void main(String[] args) {
        //打印九九乘法表
        /*
        1.先打印1列
        2.打印全部列(把1的部分变成j)
        3.去掉重复值(i<=j)
        4.调整样式(每个式子不换行,而是退格,然后j每次变化的时候就换一行)
        5.把式子里i和j的位置换掉
         */
        for(int j=1;j<=9;j++){
            for(int i = 1;i<=j;i++){
                System.out.print(i+"*"+j+"="+(j*i)+"\t");
            }
            System.out.println();
        }

    }
}

1673335920013

for循环与数组

package com.lovi.base.learn;

public class ForDemo3 {
    public static void main(String[] args) {
        //数组与for循环
        int[] numbers = {1,2,3,4,5};//定义数组
        for(int i=0;i<numbers.length;i++){
            System.out.println(numbers[i]);
        }
        //重点
        System.out.println("=====================");
        for(int x:numbers){
            //原理,把numbers的每个数组的元素都赋值给x,然后逐个输出
            System.out.println(x);
        }
    }
}

1673336322172

continue 与break与goto

1673336416546

1673336501547

1673336600169

1673336706594

1673336829953

(goto,不建议使用,了解即可)

练习

打印三角形

package com.lovi.base.learn;

public class ForDemo4 {
    public static void main(String[] args) {
        //打印三角形
        /*
        思路,先打印一半的三角形(空格)再打印一半的三角形实体
        再复制一份实体
         */
        for(int i=0;i<=5;i++){
            for(int j=5;j>i;j--){
                System.out.print(' ');
            }
            //反过来打三角形
            for(int j1=0;j1<=i;j1++){
                System.out.print('*');
            }
            //再复制一份(去掉顶角)
            for(int j1=0;j1<i;j1++){
                System.out.print('*');
            }
            System.out.println();
        }
    }
}

1673338083647

关键点是把空格也看成是打印的部分

java方法详解

何谓方法

1673338358464

方法的定义及调用

方法定义

1673340592509

形式参数与实际参数

1673340718215

在方法里,return还有一个作用是终止方法

1673340914446

方法调用

1673340990179

记住

1673341069455

方法重载

1673341130938

实例

1673341291175

命令行传参

用main方法传递参数

1673341398498

1673341687237

可变参数

必须放在最后一个参数

1673341774569

1673341867062

1673341899920

可变参数,本质是数组

package com.lovi.base.learn.method;

public class Demo1 {
    public static void main(String[] args) {
        //可变的参数
        new Demo1().happy(1,2,3,6,5,434532,32);

    }
    public void happy(int... numbers){
        for (int i=0;i<numbers.length;i++){
            System.out.println("numbers["+i+"]"+"==>>"+numbers[i]);

        }
    }
}

1673342275787

递归

1673342306136

  • 原理

1673342640512

深度大的时候不适合用递归,会占用大量的空间内存,导致电脑卡住。

能不用递归尽量不用递归。

递归主要是思想的学习。递归思想。递归只适合小基数的运算。

  • 例子
package com.lovi.base.learn.method;

public class Demo2 {
    public static void main(String[] args) {
        //用递归计算阶乘
        //5!=5*4*3*2*1;
        System.out.println(new Demo2().factorial(5));//计算5的阶乘并输出,得到120
    }
    public int factorial(int num){
        //设置边界
        if(num==1){
            return 1;
        }else {
            //不符合边界就往边界调用。5*4...
            return num*factorial(num-1);
        }
    }
}

练习

1673343182247

package com.lovi.base.learn.method;

import java.util.Scanner;

public class Demo3 {
    public static void main(String[] args) {
        /*
        写一个计算器,要求实现加减乘除功能,并且能够循环接收新的数据,通过用户交互实现。

        思路推荐:
            写4个方法:加减乘除
            利用循环+switch进行用户交互
            传递需要操作的两个数
            输出结果
         */
        double a = 0;
        double b = 0;
        String c = "a";
        int d =1;//作为循环判断
        Scanner scanner = new Scanner(System.in);

        while (d==1){
            System.out.println("《===========游戏开始==============》");
            System.out.println("请输入第一个数");
            a = scanner.nextDouble();
            System.out.println("请输入+或者-或者*或者/");
            c =scanner.next();
            System.out.println("请输入第二个数");
            b = scanner.nextDouble();

            //创造对象
            Demo3 demo3 = new Demo3();

            switch (c){
                case "+":
                    demo3.add(a,b);
                    break;
                case "-":
                    demo3.subtract(a,b);
                    break;
                case "*":
                    demo3.multiplication(a,b);
                    break;
                case "/":
                    demo3.division(a,b);
                    break;
                default:
                    System.out.println("输入不合法!!");
            }

            System.out.println("输入1继续游戏,输入0,退出游戏");
            d= scanner.nextInt();
        }



        scanner.close();
    }
    //加减乘除四个方法
    public void add(double a ,double b){
        System.out.println(a+"+"+b+"="+(a+b));
    }
    public void subtract(double a ,double b){
        System.out.println(a+"-"+b+"="+(a-b));
    }
    public void multiplication(double a ,double b){
        System.out.println(a+"*"+b+"="+(a*b));
    }
    public void division(double a ,double b){
        System.out.println(a+"/"+b+"="+(a/b));
    }


}

运行结果

《===========游戏开始==============》
请输入第一个数
10
请输入+或者-或者*或者/
+
请输入第二个数
10
10.0+10.0=20.0
输入1继续游戏,输入0,退出游戏
1
《===========游戏开始==============》
请输入第一个数
10
请输入+或者-或者*或者/
-
请输入第二个数
10
10.0-10.0=0.0
输入1继续游戏,输入0,退出游戏
1
《===========游戏开始==============》
请输入第一个数
10
请输入+或者-或者*或者/
*
请输入第二个数
10
10.0*10.0=100.0
输入1继续游戏,输入0,退出游戏
1
《===========游戏开始==============》
请输入第一个数
10
请输入+或者-或者*或者/
/
请输入第二个数
10
10.0/10.0=1.0
输入1继续游戏,输入0,退出游戏
0

Process finished with exit code 0

java数组

数组定义

1673346349834

数组声明创建

1673346403245

1673346493603

原理

1673346616595

1673346674504

1673346695166

数组的四个基本特点

1673346805761

package com.lovi.base.learn.array;

public class Demo1 {
    public static void main(String[] args) {
        //数组的声明与创建
        int[] nums;//声明
        nums = new int[10];//创建 (开辟空间)

        //初始化,让其为1,2,...10
        for(int i=0; i<nums.length;i++){
            nums[i]=i+1;
        }
        //输出
        for(int x:nums){
            System.out.println(x);
        }

    }
}

输出:

1673347256133

三种初始化以及内存分析

内存分析

1673347654931

如果我不去赋值的话,它就会走默认初始化

三种初始化

1673350808114

1673350942781

默认初始化其实就是默认值!

数组边界和小结

1673351184651

数组使用

1673351289626

1673351405151

  • for-each

1673351879877

  • 数组作方法入参

1673351944151

  • 数组作方法入参

反转数组

1673351975773

二维数组

1673352076889

二维数组

数组的数组

(原理)

1673352173830

1673352478415

原理:

1673352532310

1673352654362

例子

package com.lovi.base.learn.array;

public class Demo2 {
    public static void main(String[] args) {
        //二维数组的理解与应用
        int[][] nums = {{1,2},{3,4},{5,6},{7,8}};

        //输出一下
        System.out.println(nums[0]);//打印出来的是对象

        //用取出每一个值的方法打印才行
        printArray(nums[0]);
        System.out.println("取出每个数据");
        System.out.println(nums[0][1]);


    }
    //打印数组元素
    public static void printArray(int[] arrays){
        for (int i = 0; i < arrays.length; i++) {
            System.out.print(arrays[i]+" ");
        }
        System.out.println();
    }
}

1673353265338

Arrays类讲解

1673353359802

实例

package com.lovi.base.learn.array;

import java.util.Arrays;

public class Demo3 {
    public static void main(String[] args) {
        //Array类的几个妙用,说白了它是个工具类,里边有很多方法可以用,就很方便
        int[] nums = {1, 3, 2, 32, 432, 11, 23, 43, 34};

        //数组输出
        System.out.println(nums);//就只是对象
        System.out.println(Arrays.toString(nums));

        //数组排序
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums));


        //数组填充(在下标2,和4之间填充6,(不包括4))
        Arrays.fill(nums,2,4,6);
        System.out.println(Arrays.toString(nums));
    }
}

1673354384040

排序

一共有八大排序

参考教程:https://blog.csdn.net/m0_63111921/article/details/123796971

一,选择排序-直接插入排序(Direct insertion sort)
  1. 元素集合越接近有序,直接插入排序算法的时间效率越高

2.时间复杂度:O(n^2)(情况最差时,即逆序转有序,最好为O(n));

3.空间复杂度:O(1);

4.稳定

package com.lovi.base.sort;

import java.util.Arrays;

public class Demo01 {
    //插入排序(从小到大排列)
    public int[] InsertSort(int[] a){
        //要插入的轮数
        for (int i = 0; i < a.length-1; i++) {
            int temp = a[i+1];//要插入数数据
            int end=i;//要比较的值的下标
            //end>=0保证往前每个都比较
            while (end>=0){
                //保证从小到大。
                // 如果要插入的数据比前面的小,原本temp占用的位置空出来,给前面的退后。
                if (temp < a[end]){
                    a[end+1]=a[end];//原本前面的退后
                    end--;//比较的值的往前移动(下标-1)
                }else {
                    break;
                }
                a[end+1]=temp;
            }

        }

        return a;
    }
    public static void main(String[] args) {
        int a[] = {8, 7, 6, 5, 4, 3, 2, 1};
        int b[] = {1,4,2,8,2,4,1,3,2};
        new Demo01().InsertSort(a);
        System.out.println(Arrays.toString(a));//结果:[1, 2, 3, 4, 5, 6, 7, 8]


    }
}

二,插入排序-希尔排序(Shell sort)

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  3. 希尔排序的时间复杂度不好计算,需要进行推导,推导出来平均时间复杂度: O(N1.3—N2)
  4. 稳定性:不稳定
package com.lovi.base.sort;

import java.util.Arrays;

public class Demo02 {
    //希尔排序(从小到大排列)
    public int[] ShellSort(int[] a){
        int gap = a.length;

        while(gap>1)//判断是否还需排序
        {
            gap=(gap/3+1);//保证最后一次直接插入排序
            for(int i=0;i<a.length-gap;i++)//进入循环,对每一组进行排序
            {
                int end=i;
                int tmp=a[end+gap];
                while(end>=0)
                {
                    if(tmp<a[end])
                    {
                        a[end+gap]=a[end];
                        end-=gap;
                    }
                    else
                    {
                        break;
                    }
                    a[end+gap]=tmp;
                }
            }
        }

        return a;
    }
    public static void main(String[] args) {
        int a[] = {8, 7, 6, 5, 4, 3, 2, 1};
        new Demo02().ShellSort(a);
        System.out.println(Arrays.toString(a));//结果:[1, 2, 3, 4, 5, 6, 7, 8]


    }
}

三,选择排序-简单选择排序(Simple selection sort)

1,容易理解,但是效率太低,实际当中不太使用

2,时间复杂度O(n^2),空间复杂度O(1);

3,不稳定

package com.lovi.base.sort;

import java.util.Arrays;

public class Demo03 {
    //希尔排序(从小到大排列)
    public int[] selectSort(int[] a) {
        int left = 0;
        while (left < a.length) {
            int min = left;
            for (int i = left; i < a.length; i++)//找最小值
            {
                if (a[min] > a[i]) {
                    min = i;
                }
            }
            //交换数据   然后找次小,交换
            int temp = a[left];
            a[left] = a[min];
            a[min] = temp;
            
            left++;
        }
        return a;

    }
    public static void main(String[] args) {
        int a[] = {8, 7, 6, 5, 4, 3, 2, 1};
        new Demo03().selectSort(a);
        System.out.println(Arrays.toString(a));//结果:[1, 2, 3, 4, 5, 6, 7, 8]

    }
}
冒泡排序

时间复杂度为O(n2)

package com.lovi.base.sort;

import java.util.Arrays;

public class Demo05 {
    //冒泡排序
    public int[] bubbleSort(int[] a){
        //外层循环,冒泡排序的轮数
        for (int i = 0; i < a.length-1; i++) {
            //内层循环,每轮交换的次数
            for (int j = 0; j < a.length-1-i; j++) {
                //开始交换,从小到大排,小的在前面,若发现大的在前面就换
                if(a[j]>a[j+1]){
                    int temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }

            }
        }
        return a;
    }

    public static void main(String[] args) {
        int a[] = {8, 7, 6, 5, 4, 3, 2, 1};
        new Demo05().bubbleSort(a);
        System.out.println(Arrays.toString(a));//结果:[1, 2, 3, 4, 5, 6, 7, 8]

    }
}

四,选择排序-堆排序(Heap sort)

。。。。

稀疏数组

1673364658558

例子

1673364680879

  • 解答
package com.lovi.base.learn.array;

public class Demo5 {
    public static void main(String[] args) {
        //稀疏数组,了解即可
        //1.打印出原来的数组
        int[][] a1 = new int[11][11];
        a1[1][2]=1;
        a1[2][3]=2;
        System.out.println("原数组");
        //打印数组
        for (int i = 0; i < a1.length; i++) {
            for (int j = 0; j < a1.length; j++) {
                System.out.print(a1[i][j]+"\t");
            }
            System.out.println();
        }

        //2.打印出稀疏数组
            //先算出有效数字才知道多少行!
        int sum=0;//有效数字
        for (int i = 0; i < a1.length; i++) {
            for (int j = 0; j < a1.length; j++) {
                if(a1[i][j]!=0){
                    sum++;
                }
            }
        }
        System.out.println("有效数字==》"+sum);

        int[][] a2 = new int[sum+1][3];
        //行 列 值
        a2[0][0]=11;
        a2[0][1]=11;
        a2[0][2]=sum;
        //遍历二维原数组,将非0的值放入稀疏数组中
        int count=0;//计数器
        for (int i = 1; i < a1.length; i++) {
            for (int j = 0; j < a1.length; j++) {
                if(a1[i][j]!=0){
                    count++;
                    a2[count][0]=i;
                    a2[count][1]=j;
                    a2[count][2]=a1[i][j];
                }
            }

        }
        System.out.println("稀疏数组");
        //打印数组
        for (int i = 0; i < a2.length; i++) {
            for (int j = 0; j < a2.length; j++) {
                System.out.print(a2[i][j]+"\t");
            }
            System.out.println();
        }

        //3.打印出稀疏数组还原的数组
        int[][] a3 = new int[a2[0][0]][a2[0][1]];
            //给有效值赋值
        for (int i = 1; i < a2.length; i++) {
            a3[a2[i][0]][a2[i][1]] = a2[i][2];
        }
        System.out.println("还原后的稀疏数组");
        //打印数组
        for (int i = 0; i < a3.length; i++) {
            for (int j = 0; j < a3.length; j++) {
                System.out.print(a3[i][j]+"\t");
            }
            System.out.println();
        }
    }
}

结果

原数组
0	0	0	0	0	0	0	0	0	0	0	
0	0	1	0	0	0	0	0	0	0	0	
0	0	0	2	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
有效数字==》2
稀疏数组
11	11	2	
1	2	1	
2	3	2	
还原后的稀疏数组
0	0	0	0	0	0	0	0	0	0	0	
0	0	1	0	0	0	0	0	0	0	0	
0	0	0	2	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	

Process finished with exit code 0

面向对象编程

初识面向对象

面向过程 & 面向对象

1673367643731

1673367689379

方法回顾和加深

1673420612419


方法的调用

1673424544696

1673424564666

1673424579244

结论:同类型的方法可以互相调用!

原理:

1673424728434


形参和实参(值传递)

1673424876226

引用传递

1673425042718

对象的创建分析

类和对象的关系

1673432434850

1673432839371

  • 类与对象关系探索

实例

1673433475151

代码

Student

package com.lovi.base.learn.oop.demo1;

public class Student {
    //属性
    String name;
    int age;

    //方法
    public void study(){
        System.out.println("学生在学习!");
    }
}

Application

package com.lovi.base.learn.oop.demo1;


public class Application {
    public static void main(String[] args) {
        //一个项目应该只有一个启动类!
        /*
        类:抽象的,可以被实例化
        类实例化之后会返回一个对象
        student1和student2都是对象
        student对象就是Student类的一个具体的实例
         */
        Student student1 = new Student();
        Student student2 = new Student();

        String xiaoMing = student1.name = "小明";
        student1.age = 18;
        student2.name = "小红";
        student2.age = 6;

        //输出属性
        System.out.println(xiaoMing);
        System.out.println(student1.age);
        System.out.println(student2.name);
        System.out.println(student2.age);

        //方法调用!
        student1.study();
    }
}

构造器详解

例子

1673497928922

关键点

/*
构造器:
1. 和类名相同
作用:
2. 没有返回值
1. new 本质在调用构造方法
注意点:
2. 初始化对象的值
1. 定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
Alt + Insert
this. =
 */

代码

Person

package com.lovi.base.learn.oop.demo1;


public class Person {
    String name;
    int age;
    String gender;

    //构造器(这是隐含的)
    public Person(){

    }
    //有参数
    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}

Application

package com.lovi.base.learn.oop.demo1;


public class Application {
    public static void main(String[] args) {
        //测试person
        //无参
        Person person = new Person();
        person.name = "小白";
        System.out.println(person.name);
        System.out.println("==========");
        person = new Person("小红");
        System.out.println(person.name);
        System.out.println("==========");
        person = new Person("小黄",19);
        System.out.println(person.name+"\t"+person.age);
        System.out.println("==========");
        person = new Person("小绿",20,"女");
        System.out.println(person.name+"\t"+person.age+"\t"+person.gender);


    }
}

结果

1673498032501

创建对象内存分析

例子

1673498481731

new的时候

1673498365095

赋值的时候

1673498410685

1673498567113

类与对象小结

1. 类与对象
	类是一个模板:抽象,对象是一个具体的实例
2. 方法
    定义、调用!
3. 对象的引用
    引用类型: 基本类型(8)
    对象是通过引用来操作的:栈--->堆
4.属性:字段Field成员变量
    默认初始化:
        数字:0 0.0
        char: u0000
        boolean: false
        引用:null
    修饰符 属性类型 属性名 = 属性值!
5. 对象的创建和使用
    - 必须使用new 关键字创造对象,构造器 Person kuangshen = new Person();
    - 对象的属性 kuangshen.name
    - 对象的方法 kuangshen.sleep()
6. 类:
    静态的属性 属性
    动态的行为 方法

面向对象三大特性:封装,继承,多态

封装

1673499079276

属性私有,get、set

封装的作用

提高程序的安全性,保护数据
隐藏代码的实现细节
统一接口
系统可维护增加了
  • 实例

属性私有爆红

1673523365773

Person

package com.lovi.base.learn.oop.demo1;


public class Person {
    //属性私有,封装起来
    private String name;
    private int age;

    //get/set方法(public)给外界提供接口
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age>120||age<0){
            System.out.println("年龄不合法,系统自动判定为三岁小孩");
            this.age = 3;
        }else {
            this.age = age;
        }
    }
}

Application

package com.lovi.base.learn.oop.demo1;


public class Application {
    public static void main(String[] args) {
        //测试封装
        Person person = new Person();
        person.setName("小明");
        System.out.println(person.getName());//小明
        person.setAge(999);//年龄不合法,系统自动判定为三岁小孩
        System.out.println(person.getAge());//3


    }
}

继承

1673523825753

快捷键 ctrl+h 可以看到继承关系

定义了final的类不能被继承,没有子类,断子绝孙!

父类(基类)

派生类,子类

子类继承了父类,就会拥有父类的全部方法!

私有的东西无法被继承

实例

1673524722717

  • super

对于属性

1673524933862

对于方法

1673525013312

对于构造器

默认先执行父类的构造方法,再执行子类的,所以,子类的构造方法隐含了super();

1673525152713

super注意点:
    1. super调用父类的构造方法,必须在构造方法的第一个
    2. super 必须只能出现在子类的方法或者构造方法中!
    3. super和 this 不能同时调用构造方法!
Vs this:
    代表的对象不同:
        this: 本身调用者这个对象
    前提
        super: 代表父类对象的引用
        this:没有继承也可以使用
    构造方法
        super:只能在继承条件才可以使用
        this();本类的构造
        super():父类的构造!
  • 方法的重写

这是静态方法

1673525830722

方法的调用只和左边,定义的数据类型有关
父类的引用指向了子类
重写都是方法的重写,和属性无关

这是非静态方法

发现方法重写只和非静态方法有关

1673525925521

重写注意点

重写:需要有继承关系,子类重写父类的方法!
    1. 方法名必须相同
    2. 参数列表列表必须相同
    3. 修饰符:范围可以扩大但不能缩小: public>Protected>Default>private
	4. 抛出的异常:范围,可以被缩小,但不能扩大; ClassNotFoundException --> Exception(大)
重写,子类的方法和父类必要一致;方法体不同!
为什么需要重写:
	1. 父类的功能,子类不一定需要,或者不一定满足
Alt + Insert; override;

多态

1673526256320

1673526626224

多态学习关键点:

父类型,可以指向子类,但是不能调用子类独有的方法

左边(Student):能调用的方法都是自己的或者继承父类的!Student s1 = new Student();

对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!

子类重写了父类的方法,执行子类的方法

多态注意事项:
1. 多态是方法的多态,属性没有多态
2. 父类和子类,有联系 类型转换异常! ClassCastException!
3. 存在条件: 继承关系,方法需要重写,父类引用指向子类对象!Father f1 = new Son();

不能重写的方法:
1. static 方法,属于类,它不属于实例
2. final 常量;
3. private方法;

instanceof和类型转换

instanceof 关键,如果匹配,可以进行类型之间的转换

看有没有父子关系

1673528167672

1673528542006

1673528778695

static关键字

静态属性

1673536912729

静态方法

package com.lovi.base.learn.oop.demo1;

public class Teacher extends Person{
    //static关键字

    //静态方法
    public static void teach(){
        System.out.println("教书");
    }
    //非静态方法
    private void happy(){
        System.out.println("开心");
    }


    public static void main(String[] args) {
        Teacher.teach();
        System.out.println("==========");
        new Teacher().happy();
    }



}

1673537631532

代码块

package com.lovi.base.learn.oop.demo1;

public class Teacher extends Person{
    //static关键字

    {
        //匿名代码块,在对象创建时就有了
        System.out.println("匿名代码块!");
    }
    static {
        //静态代码块
        System.out.println("静态代码块");//只执行一次
    }
    public Teacher(){
        System.out.println("构造方法!");
    }

    //静态属性
    private static String name;
    private int age = 18;


    public static void main(String[] args) {
        new Teacher();
        System.out.println("==========");
        new Teacher();
    }

}

1673537292514

//静态导入包

package com.lovi.base.learn.oop.demo1;

import static java.lang.Math.PI;
import static java.lang.Math.random;
import static java.lang.Math.*;//通配符直接导入整个Math

public class Teacher extends Person{
    //static关键字
    //静态导入包

    public static void main(String[] args) {
        System.out.println("随机方法"+Math.random());
        System.out.println("静态导入包"+PI);
        System.out.println("静态导入包"+random());
        //Math.floor(18.1);
        System.out.println("向下取整"+floor(18.9999));

    }

}

1673538417392

抽象类和接口

抽象类

1673538549504

1673538752448

//子类必须重写抽象类的所有抽象方法 除非它自己也是抽象类
抽象类存在构造器,子类可以用super调用

接口

1673539162540

1673539427070

接口中定义的变量,其实都是常量(一般都不会这么做)

1673539568735

接口作用:
1. 约束
2.定义一些方法,让不同的人实现~ 10
3. public abstract (接口中的方法)
4. public static final (接口中的属性)
5,接口不能被实例化~,接口中没有构造方法~
6. implements可以实现多个接口
7,必须要重写接口中的方法~

内部类及OOP实战

1673539862937

1673540029349

1673540091518

方法里也能写内部类,称之为局部内部类

1673540181042

没有名字的内部类(匿名内部类)

1673540278364

异常机制

Error和Exception

1673540389371

1673540588252

1673540640501

1673540728456

1673540777412

捕获和抛出异常

1673541020378

实例

1673541136894

异常处理

1673541108840

知识:

1673541352763

快捷键:选中想要处理异常的语句,然后ctrl+alt+t(选择)

1673541441631

主动抛出异常与方法上抛出(处理不了)

1673541568079

自定义异常及经验小结

1673541610796

实例

1673541977719

测试

1673542036074

代码

package com.lovi.base.learn.exception;

//自定义异常
public class A extends Exception {
    //传递的数字大于10则抛出异常
    private int a;

    public A(int a) {
        this.a = a;
    }
    //打印异常信息

    @Override
    public String toString() {
        return "我的自定义异常{" +
                "异常=" + a +
                '}';
    }
}

package com.lovi.base.learn.exception;

public class Test {
    //可能存在异常的方法(抛出我的自定义异常)
    public void test(int a)throws A{
        if(a>10){
            throw new A(a);//主动抛出异常
        }
        System.out.println("OK");
    }

    public static void main(String[] args) {
        try {
            new Test().test(12);
        } catch (A e) {
            System.out.println("测试异常捕获==》"+e);
        } finally {
        }
    }
}

1673542862295

异常处理小贴士

1673542166680

posted @ 2023-01-29 15:10  Lovi*  阅读(133)  评论(0)    收藏  举报