JAVA基础

前言

本人本科计算机专业,记录一下从零开始的 Java 学习,学习资源是黑马程序员的从入门到起飞。分享一下记录的笔记和代码,欢迎一起交流,共勉。笔记随着进度不定期更新

java 基础

Java 入门

常用 cmd 指令
  • E:盘符切换

  • dir 查看当前路径下内容

  • cd 进入目录

  • cd … 退回上一级目录

  • cd\ 回到根目录

跨平台原理

高级语言编译运行方式

  • 编程:.java
  • 编译: .o 二进制
    • 编译型语言不同的操作系统需要重新编译
    • 解释型语言按行翻译,不生成新文件
    • java 是混合型,先编译成 .class,再交给虚拟机按行执行
  • 运行
JRE和JDK

JDK (java 开发工具包)

JDK = JVM + 核心类库 +开发工具

JVM:java虚拟机 代码运行的地方

核心类库

开发工具:javac、java、jdb

JRE(java运行环境)

JRE = JVM + 核心类库 + 运行环境


基本概念

注释
  • 单行注释 //这是一个注释
  • 多行注释/*多行注释*/
  • 文档注释/**文档注释*/
关键字

关键字字母全部小写

编译器中高亮显示

class:创建一个类

字面量

整数、小数、字符串、字符、布尔、空类型(null)

  • “” “ ”都是字符串

  • null 不能直接输出需要用字符串形式输出

  • \t 制表符:打印时把前面的字符串的长度补到 8 或者 8 的倍数

package com.itheima.java;

public class text {
    public static void main(String[] args) {
        System.out.println("name"+'\t'+"zjq");
        System.out.println("age "+'\t'+"23");
    }
}

name zjq
age 23

计算机的存储规则

text、image、sound

计算机中任意数据都是以二进制存储的

文字数据

通过转二进制和转码表存储

  • Unicode编码:国际标准字符集,包含各国文字

图片数据

分辨率、像素、三原色

  • 设置软件大小的时候用像素描述
  • 美学三原色(红黄蓝)、光学三原色(红绿蓝 即RGB 取值范围0~255)
  • 像素点是由红绿蓝顺序排列组成的,权重不同

声音数据

用波形图存储

数据类型

基本数据类型

四类八种

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oQYVbOzs-1668143680466)(/Users/mac/Documents/img/截屏2022-10-17 20.00.28.png)]

  • long /float 类型定义需要在数字后面加 L /F 作为后缀 long n = 100L;

引用数据类型

标识符

给__类、方法、变量__等起的名字

由数字、字母、_ 、$ 组成

  • 小驼峰命名法:方法、变量 firstName 、 firstNameNumber
  • 大驼峰命名法:类名 GoodStudent
键盘录入

java 帮我们写好了一个类叫 Scanner

import java.util.Scanner;
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();

体系一:

nextInt();//接收整数
nextDouble();//接收小数
next();//接收字符串

遇到空格,制表符,会车就停止接收。如abc bcd:bcd会留在缓存区,自动赋给第二个键盘录入

体系二

nextLine();//接收字符串

  • 两种体系不可以混用
IDEA

IDEA 项目结构

  1. project(微信)
  2. module(消息、通讯录、发现、我)
  3. package(相同功能的代码放在一个包里)
  4. class ( 修改类名的时候要和文件名一起修改)

运算符

六种

算术运算符

+、-、*、/、%

  • 在代码中,如果有小数参与运算,结果有可能不精确
  • 数字进行运算时,需要穿换成相同类型才可以运算

类型转换

  • 隐式转换:把一个__取值范围小__的数值,转成__取值范围大__的数据

byte < short < int < long < float < double

byte short char 在进行运算时,都会先提升为 int 再运算

  • 强制转换:把一个取值范围大的数值,赋值给取值范围小的变量,需要加入强制转换
double a = 300;
int b = (int)a;

字符串的 “+” 操作

当 “+” 的操作中出现字符串时(“+”的两边存在字符串),“+” 是字符串连接符,拼接后形成一个新的字符串

  • 拼接的时候会把变量的值拿出来拼接

  • 连续进行 “+” 操作室,从左到右逐个执行

1 + 99 + "岁"

>>>“100岁”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4CF7OaD7-1668143680470)(/Users/mac/Documents/img/截屏2022-10-17 21.25.44.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySYQSWAb-1668143680471)(/Users/mac/Documents/img/截屏2022-10-17 21.30.06.png)]

自增自减运算符

++ 、 –

  • 单独使用:结果相同
  • 参与运算:a++ , ++a
//先用后加
int a = 10;
int b = a++;//10
//先加后用
int a = 10;
int b = ++a;//11
赋值运算符

=、+= … …

  • += 底层隐藏了一个强制转换类型
short s = 1;
s += 1;
//等同于 s = (short)(s + 1);
关系(比较)运算符

== 、 != 、四种大小关系

  • 关系运算符的结果都是 boolean 类型
逻辑运算符

&(与) 、|(或)、^(异或)、!(非)

  • 短路运算符:&&(而且)、||(或者) —> 提高代码效率
三元运算符

关系表达式 ? 表达式 1 : 表达式 2

a > b ? a : b
算术符优先级

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5dv7Hlq-1668143680472)(/Users/mac/Documents/img/截屏2022-10-17 21.59.44.png)]

原码、反码、补码
  • 原码:十进制数据的二进制表现形式,最左边是符号位,0 位正,1 为负(一个字节 -128 ~ 127)

用原码对正数进行加法运算,不会出现问题,但如果是负数运算就会出现问题,实际运算方向正好相反

-1 + 1 = -2

  • 反码:正数反码不变,负数符号为不变,数值取反

为了解决负数的运算发明了反码

结果跨 0 会产生误差,结果差1

  • 补码:反码 + 1

反码跨 0 产生错误是因为反码的0有两个,补码则解决的这个问题

最终数值的在计算机中以补码形式储存和运算

  • 规定:1000 0000 表示 -128 它既没有原码也没有反码

其他运算符

& 、 |

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awAZXHKg-1668143680476)(/Users/mac/Documents/img/截屏2022-10-17 23.28.46.png)]

  • << :向左移动,低位补 0
  • >>:向右移动,高位补 0 或 1(愿数字的正负)
  • >>>:无符号右移,高位补 0

判断和循环

分支结构

If 、switch

if 一般用于范围的判断,switch用于有限数据一一列举

if (关系表达式1){
  语句体1} else if(关系表达式2){
  语句体2} else{
  语句体3}
  • 语句表达式是布尔类型时,不需要 == ,直接把变量写在小括号中就可以
switch(表达式){
  case1:
    语句体1break;
  case2:
    语句体2break;
    
  ...
    
  default:
    语句体 n + 1break;
}
  • 表达式可以是:byte 、short 、 int 、char 、枚举(JDK5)、String(JDK7)
  • case 后面的值只能是字面量,不能是变量,且不可重复
  • case 后可以接多个条件 ,如:case 1,2,3;

default

  • 可以写在任意位置
  • 可以省略,但不建议

case 穿透

  • break 不可以省略,省略会导致穿透

switch 新特性(JDK12)

switch (day){
            case 1,2,3 -> {System.out.println("1");}

            case 4,5 ->{System.out.println("2");}

            default -> {System.out.println("吃屁");}

        }
  • 不用担心穿透
循环结构

for 、while 、 do…while

for(初始化语句;条件判断语句;条件控制语句){
  循环体;
}
while(条件判断语句)	{
  循环体语句;
  条件控制语句;
}

for 和 while 区别

  • for 中控制循环的变量在语法结构里,循环结束后不能再次使用,while 则可以重复使用
  • for 用于知道循环次数和循环范围
  • while 用于知道循环结束的条件
初始化语句;
do{
  循环体语句;
  条件控制语句;
}while(条件判断语句);
无限循环
for(;;){}
while(true){}//常用
循环控制
  • continue :结束本次循环,继续下次循环
  • break :结束整个循环,如果是 while 嵌套 switch ,break 只能跳出 switch,使用循环命名的方式可以避免(loop)

数组

存储同种数据类型的多个值

存在隐式转换情况,但尽量避免这类情况

数组的定义和初始化

两种格式

int[] array//更常用
int arry[]

静态初始化

在内存中为数组容器开辟空间,并存入数据

int[] array =new int[]{11,22,33};//完整格式
int[] array ={11,22,33};//简化格式
  • 数组定义之后大小不可改变

数组的地址值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5meUO8dt-1668143680477)(/Users/mac/Documents/img/截屏2022-10-18 19.53.51.png)]

  • [ :表示当前是一个数组
  • D :表示数组里面的元素是 double 类型
  • @ :间隔符号,固定格式
数组元素访问
int[] arr = {1,2,3};
sout(arr[0]);//访问
arr[0] = 100;//修改,也可以是变量
  • 数组修改后,被覆盖的原数据就不存在了
数组的遍历
int[] arr = {1,2,3,4,5};
//arr.fori
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}
数组的动态初始化

指定数组长度,由系统分配元素的值

int[] arr = new int[5];

数组默认初始化值规律

  • 整数: 0
  • 小数: 0.0
  • 字符型: ‘/u0000’ (表示空格)
  • 布尔: false
  • 引用 :null
数组的内存图

java的内存分配(JAM)

  • 栈:方法运行时使用的内存,比如 main 方法运行时,进入方法栈中执行

  • 堆:存储对象或者数组,new 来创建的,都存储在堆内存里( new 就是在堆里开辟了一个小空间,多个 new 就开辟了多个小空间)

  • 方法区:存储可以运行的 class 文件

  • 本地方法栈:JVM在使用操作系统功能的时候使用,和我们开发无关

  • 寄存器:给 CPU 使用,和我们开发无关

二维数组

当我们需要把数组分组管理时,需要用的二维数组

  • 静态初始化
int[][] arr = {
  {11,22},
  {33,44}
}

定义时每个一维数组单独占据一行

  • 动态初始化
int[][] arr = new int[2][2]
  • 二维数组遍历
int[][] arr = {
  {11,22},
  {33,44}
};
for (int i = 0; i < arr.length; i++) {
            for (int j = 0;  j< arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
        }

特殊情况

  • 后添加一维数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxE02Xdb-1668143680479)(/Users/mac/Documents/img/截屏2022-10-19 21.49.20.png)]

初始arr[0] arr[1]存储的地址值为null

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ycH5K1E-1668143680486)(/Users/mac/Documents/img/截屏2022-10-19 21.50.47.png)]

旧的一维数组地址值可以直接覆盖

数组使用技巧
  • 遍历二十六个字母
(char)('a'+1) -> 'b'

方法

方法是程序中最小的执行单元

  • 提高了代码的复用性和可维护性
方法的定义
public static 返回值类型 方法名 (参数){
  方法体;
  return 返回值;
}

参数

  • 形参:方法定义中的参数
  • 实参:方法调用中的参数

方法定义的小技巧

  • 我要干什么 --> 方法体
  • 做这件事需要什么才能完成 --> 形参
  • 是否需要结果 --> 是否需要返回值

返回值

  • 为了拿到方法的结果,去编写另一段代码逻辑

方法注意事项

  • 方法不调用不执行
  • 方法之间是平级关系,不能互相嵌套定义
  • 方法编写顺序和执行顺序无关
  • 没有返回值时,return;表示结束方法
  • return 下面,不能编写代码,属于无效代码
方法的重载

在同一个类中,定义了多个同名的方法,这些同名的方法具有同种功能。

每个方法具有不同的参数类型参数个数,这些同名的方法构成了重载关系

简单记:同一个类中,方法名相同参数不同的方法。与返回值无关

  • 参数不同:个数、类型、顺序
  • 顺序不同可以构成重载,但不建议
  • 习惯把相同功能的方法起一样的名字

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wfdq3Unl-1668143680488)(/Users/mac/Documents/img/截屏2022-10-18 21.11.45.png)]

return 和 break 区别

  • return 用于方法,表示结束方法和返回结果
  • break用于循环,结束循环或者 switch
方法的内存

方法调用的基本内存原理

先进后出、后进先出

基本数据类型和引用数据类型

基本数据类型的数据值存储在自己的空间中

引用数据类型的数据值存储在其他空间中。赋值时赋的是地址值

  • 基本数据类型里存储的是真实的数据
  • 引用(使用其他空间的数据)数据类型时 new 出来的。如 arr 。变量中存储的是地址值

方法的值传递

  • 传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实参的值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xOJfLxS7-1668143680492)(/Users/mac/Documents/img/截屏2022-10-18 22.03.57.png)]

number 仍是 100

  • 传递引用数据类型时,传递的是地址值,形参的改变,影响实参的值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EVJSRg6q-1668143680493)(/Users/mac/Documents/img/截屏2022-10-18 22.05.29.png)]

arr[1] 的值是 200

方法快捷方式

command + option +M : 自动抽取方法

command + B :快速跳转同名方法

Command + option + T : 整体嵌套


面向对象

找东西来解决问题

  • 特点:封装、继承、多态

  • 优点:符合人类思维习惯,编程更简单,更好理解

  • 学什么:

    • 学习已有对象并使用
    • 学习如何自己设计对象并使用
类和对象
  • 类:是对象共同特征的描述
  • 对象(实例):是真实存在的具体东西

在 JAVA 中,必须先设计类,才能获得对象

定义类

public class 类名{
  1.成员变量(代表属性,一般是名词)
  2.成员方法(代表行为,一般是动词)
  3.构造器
  4.代码块
  5.内部类
}
  • 用来描述一类事物的类,叫做:javabean 类。javabean 类中,不写 main 方法。

  • 在以前,编写 main 方法的类叫做测试类。可以在测试类中创建 javabean 类的对象并进行赋值调用

  • 一个 java 文件中可以定义多个 class 类,且只有一个类是 public 修饰,该类为代码文件名。

  • 实际开发中,一个文件定义一个类

获得类的对象

类名 对象名 = new 类名();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5H0lYyIx-1668143680495)(/Users/mac/Documents/img/截屏2022-10-19 22.10.03.png)]

封装

如何正确设计对象的属性和方法

  • 原则对象代表什么,就得封装对应的数据,并提供数据对应的行为(画圆是圆的方法)

private 关键字

  • 是一个权限修饰符
  • 可以修饰成员变量和成员方法
  • 被 private 修饰的成员只能在本类中才能访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-malRzvfH-1668143680499)(/Users/mac/Documents/img/截屏2022-10-20 08.53.12.png)]

this 关键字
  • 成员变量:类的里面,方法外面
  • 局部变量:方法里面

变量中遵循就近原则,为了区分成员变量和局部变量,引入了 this 关键字

this.name(成员变量) = name(局部变量);

构造方法

在创建对象时,由虚拟机自动调用,给成员变量进行初始化的

特点

  • 方法名与类名相同,大小写也要一致
  • 没有返回值类型,void 都没有
  • 没有返回值,没有 return
  • 不能手动调用,由虚拟机调用
  • 创建一次对象,就会调用一次构造方法
  • command + P :在创建对象时,可以展示构造方法的参数

注意事项

  • 如果我们自己没有写任何构造方法,虚拟机会给我们添加一个空参数构造器
  • 如果我们已经定义了有参数的构造方法,虚拟机不再为我们添加无参构造
  • 不管什么情况,都会书写无参构造和带全部参数的构造
标准 javaBean
  1. 类名需要见名知意
  2. 成员变量使用 private 修饰
  3. 至少提供给两个构造方法
  4. 提供每一个成员对应的 set()和get()

快捷键 command + N

  • Constructor :构造方法
  • Getter and Setter

Ptg:双击 + Ptg to javabean

对象的内存图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTttKEVQ-1668143680502)(/Users/mac/Documents/img/截屏2022-10-20 09.50.29.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CUDlWmr0-1668143680503)(/Users/mac/Documents/img/截屏2022-10-20 10.00.38.png)]
  • 两个对象时,class 字节码文件不需要加载两次

两个引用可以指向同一个对象,原理类似数组

引用数据类型

本质其实是变量中存储的是地址值、值存储在堆中

  • 例如:数组、对象
  • 赋值赋的是地址值
this 的内存原理

this 的本质:所在方法调用者的地址值

成员变量和局部变量区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TFP26wsl-1668143680505)(/Users/mac/Documents/img/截屏2022-10-20 10.27.53.png)]

souf
System.out.printf("你好啊%s",“张三”)
  • 不具有换行效果

字符串

API

应用程序编程接口。

即别人已经写好的东西,不需要自己编写,直接使用即可

java API :指的是 JDK 中提供的各种功能的 java 类

已经学习过的API

  • Scanner :键盘录入
  • Random :随机数

API帮助文档

  1. 打开 API 帮助文档
  2. 点击显示,并找到索引下面的输入框
  3. 搜索类名,并点击显示
  4. 查看类所在的包
  5. 查看类的描述
  6. 查看构造方法
  7. 查看成员方法
  • lang 包在使用时不需要 import 导包
String

定义在 java.lang 包中

  • 字符串的内容是不会发生改变的,它的对象在创建后不能更改
  • 字符串的拼接是创建了新的字符串

创建 String 对象的两种方式

  • 直接赋值 String name = "sb"
  • new :

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O88TpVp5-1668143680506)(/Users/mac/Documents/img/截屏2022-10-20 21.16.51.png)]

  • 通过字符数组,可以实现字符串内容的修改

  • 字节数组应用于网络中的数据传输

StringTable :串池

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dcSVUH1-1668143680507)(/Users/mac/Documents/img/截屏2022-10-20 21.24.53.png)]

  • 直接赋值时:串池中如果已经存在,会直接复用,而不是创建一个新的空间
  • new 时:每次 new 都会在里新创建一个小空间,不存在复用现象
  • 键盘录入的字符串:存储在堆中
  • 直接赋值可以节约内存,代码简单

字符串比较

比较常用方法:

  • == :基本数据类型比较数据值;引用数据类型比较地址值
  • boolean result = s1.equals(s2) :完全一样才是真
  • boolean result = s1.equalsIgnoreCase(s2) : 忽略英文大小写

遍历字符串

  • charAt(int index) : 根据索引返回字符串
  • length() : 返回字符串的长度

注意区分 arr.length 和 s.length()

遍历格式:str.length().fori

经典案例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FlSY3QRO-1668143680509)(/Users/mac/Documents/img/截屏2022-10-20 21.52.35.png)]

  • 判断几个大写字母、几个小写字母、几个数字

字符串截取

String substeing(int beginIndex,int endIndex)

String substring(int beginIndex)//截取到末尾

  • 包头不包尾,包左不包右
  • 只有返回值才是截取的小串

字符串替换

String replace(旧值,新值)

  • 只有返回值才是替换之后的结果,原字符串并未被修改,修改结果变成了一个新的字符串
StringBuilder

可以看成一个容器,创建之后里面的内容是可变的

  • 作用:提高了字符串的操作效率
  • java 对 StringBuilder 做了特殊处理,打印的是不是地址值而是属性值

构造方法

  • 空参构造
  • 有参构造:public StringBulider(String str)

常用方法

  • append(任意类型):添加数据
  • reverse():反转容器内容
  • length():返回长度
  • toString():把 StringBuilder 转换成 String ,以返回值的形式,原容器仍然存在

链式编程

当我们在调用一个方法的时候,不需要用变量接收他的结果,可以继续调用其他方法

  • 把方法的调用都写在一行
String result = new StringBuilder().append(str).reverse().toString();

使用场景 :字符串的拼接和字符串的反转

StringJoiner

也可以看作一个容器,创建后内容可变

  • 提高字符串的操作效率,代码非常简洁
  • JDK 8 出现的

构造方法

  • 无空参
  • StringJoiner(间隔符号)
  • StringJoiner(间隔符号,开始符号,结束符号)

成员方法

  • add(添加的内容) :返回容器本身,可以链式编程,只可以添加字符串类型
  • length() :以返回值的形式
  • toString() :以返回值的形式
字符串底层原理
  1. 字符串存储的内存原理
  2. ==号比较的到底是什么
  3. 字符串拼接的底层原理
    • 等号右边没有变量参与:触发字符串的优化机制,在编译的时候就已经是最终结果了,会复用串池里的字符串
    • 等号右边有变量参与:JVM 通过 StringBuilder 实现,每一行的拼接,都会创建新的字符串,浪费内存
  4. JDK 8 字符串拼接的底层原理
    • 预估字符串长度,创建相应长度的数组
  5. StringBuilder 提高效率原理图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AKlSaRUM-1668143680510)(/Users/mac/Documents/img/截屏2022-10-21 20.25.06.png)]

  • 只要有变量参与,就会有 new 出现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y8SzxcuM-1668143680511)(/Users/mac/Documents/img/截屏2022-10-21 20.31.41.png)]


ArrayList

集合:长度可变的容器

  • 自动扩容
  • 数组可以存基本数据类型和引用数据类型
  • 集合不可以直接存基本数据类型,需要用到包装类

泛型:限定集合中存储数据的类型

构造方法:ArrayList<泛型> list = new ArrayList<>();

  • 打印对象是集合中的数据类型
  • 打印时用[]对数据进行了包裹

成员方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lNvjWEsQ-1668143680515)(/Users/mac/Documents/img/截屏2022-10-21 21.27.28.png)]

  • add :不管添加什么内容一定成功,返回值一定为真
  • remove :根据内容删除返回 boolean ,根据索引返回删除值
  • set : 返回被覆盖的值
  • size :集合的长度

包装类

用于添加基本数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ke9lsZ2J-1668143680519)(/Users/mac/Documents/img/截屏2022-10-21 21.35.52.png)]

按住 option 可以竖着选择


java 强化

继承

static

静态修饰符,可以修饰成员方法、成员变量

  • 静态一定是先于对象创建的
  • 静态的~共享的

静态变量

public static String teacher

特点:

  • 被该类所有对象共享
  • 不属于对象,属于类
  • 静态变量是随着类的加载而加载,优先于对象出现

调用方法:推荐用类名调用,也可以用对象名调用

静态区 :静态变量的存储位置,单独存在堆中

  • 静态变量是随着类的加载而加载,优先于对象出现
  • 可以在创建对象前,先对类的静态变量赋值
  • 静态区的变量是共享的,独一份

静态方法

被修饰的成员方法

  • 多用在测试类和工具类中
  • javabean 类中很少会用

调用方法:推荐类名,还可以用对象名

工具类:不是用来描述一类事物的,而是帮我们做一些事情的类

  • 类名见名知意

  • 私有化构造方法(工具类是帮我们做一些事情的,创建他的对象没有任何意义)

  • 方法定义为静态(用类名调用)

static 注意事项

  • 静态方法只能访问静态
  • 非静态方法可以访问静态和非静态
  • 静态方法里没有 this 关键字

非静态方法在调用时,虚拟机默认添加了 this 参数(this 存储着调用方法对象的地址)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Umrf6JIH-1668143680520)(/Users/mac/Documents/img/截屏2022-10-23 19.16.08.png)]

=> 非静态的东西与对象有关(需要 this 调用对象),静态的东西是共享的(与类有关与对象无关,所以不需要 this )

-> main 被 static 修饰,所以在测试类中定义的方法必须被 static 修饰,才可以被调用

继承基础

提高代码复用性

  • java 提供了一个关键字 extends ,用这个关键字,我们可以让一个类和另一个类建立起继承关系

public class Student extends Person{}

  • Student 称为子类(派生类),Person 称为父类(基类或超类)

什么时候用继承?

  • 当类与类之间,存在相同的内容,并满足子类是父类中的一种名就可以考虑使用继承,来优化代码
继承的特点
  • java 只支持单继承,不支持多继承,但支持多层继承(直接父类,间接父类)
  • 每一个类都直接或者间接的继承于Object类
  • 子类只能访问父类中的非私有的成员
子类到底能继承什么

继承的是类的初始化信息,与父类创建对象后修改值无关

  • 构造方法都不能
  • 成员变量都能,在堆内存里分为两个空间存储,一部分存父类的成员变量,一部分存本类的成员变量
  • 成员方法,虚方法可以,否则不能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ib6aO5UV-1668143680521)(/Users/mac/Documents/img/截屏2022-10-23 19.59.49.png)]

构造方法:

  • 构造方法必须与类名相同,无法继承构造方法

成员变量:

  • 子类继承的私有成员变量不能直接调用,需要用 getter
  • 可以根据内存图,在 new 出来的空间里继承的成员变量和本类的成员变量是分开存储的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0NjSvaM-1668143680521)(/Users/mac/Documents/img/截屏2022-10-23 20.12.08.png)]

成员方法

  • 子类继承父类的所有虚方法

虚方法表:

再调用方法时,不需要再一层一层找

  • 虚方法:非 private、static、final

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-21NLwxnI-1668143680526)(/Users/mac/Documents/img/截屏2022-10-23 20.19.42.png)]

继承的访问特点

成员变量的访问特点:

就近原则:谁离我近,我就用谁

  • 局部变量 > 本类成员变量 > 父类成员变量
  • this 代表本类,找不到找父类
  • super 代表父类(最近的父类)

核心一定是就近原则,每次调用本类父类成员变量时,不一定要用 this super ,先看就近原则

成员方法的访问特点:

  • 同样是就近原则
  • 父类方法用 super,用在方法里
  • 子类方法嵌套方法时,也满足就近原则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JgM6vVPK-1668143680527)(/Users/mac/Documents/img/截屏2022-10-24 16.55.53.png)]

方法的重写

Def:当父类的方法不能满足子类现在的需求时,需要进行方法的重写

书写格式:一摸一样的方法声明(名称、形参)

@Override 重写注解:写在子类重写方法前

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcHw4PWf-1668143680529)(/Users/mac/Documents/img/截屏2022-10-24 17.01.23.png)]

本质:子类覆盖了从父类继承过来的虚方法

注意事项:

  • 重写方法的名称、形参列表必须与父类一致
  • 子类访问权限大于等于父类
  • 返回值类型小于等于父类
  • 建议,重写方法与父类格式保持一致
  • 只有虚方法才可以重写

构造方法访问特点

  • 父类构造方法不能被子类继承
  • 子类中所有的构造方法默认先访问父类中的无参构造,再执行自己

为什么?

  • 子类在初始化的时候,又肯呢个会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
  • 子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
  • 无参构造就是完成了成员变量的初始化

怎样调用父类构造方法?

  • 子类构造方法的第一行默认语句都是:super(),不写也存在,且必须在第一行
  • 如果想调用父类的有参构造,必须手动写 super 进行调用super(name,age)
  • this()、super()都是调用类的构造方法,一个调用本类的构造方法,一个调用父类的构造方法
this、super 使用总结
  • this :理解为一个变量,表示当前方法调用者的地址值
  • super :代表 new 出来的在堆中存放父类成员变量的地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmJgn8c3-1668143680532)(/Users/mac/Documents/img/截屏2022-10-24 19.53.28.png)]

  • this 访问本类构造方法,可以设置对象使用无参构造时成员变量的默认值
    • 无参构造里有 this 时,无参构造里的 super()消失,因为 this 调用的本类有参数构造里,第一行已存在 super()

带有继承结构的 javabean 类

  • 成员变量全部私有
  • 构造方法至少提供两个,无参和全参
  • getter 和 setter 不用写父类的成员变量,只需要写子类的getter、setter

个人理解

id 、this.id 、super .getId()

  • 本质依旧是就近原则
  • 是堆中存放父类成员变量、虚方法表的更新
  • 堆中存放成员变量的空间和虚方法表都是分为两部分的
  • 继承时多级父类的同名成员变量、虚方法存在覆盖现象,虚方法在继承时,保留着与提供该虚方法的类的关联关系
  • 虚方法覆盖的本质是在虚方法表中同名的方法共用一个索引,但仍可以用 super 调用同名的父类方法
  • 变量按照本类局部变量 -> 本类成员变量 -> 父类成员变量(依旧就近)的顺序,分别于 id this super 对应如果同名变量不超过三个存在一对多的情况
  • 方法则是按照本类方法 -> 父类虚方法的顺序,分别与this super 对应,也存在一对多的情况

多态

同类型的对象,表现出不同形态

把子类对象赋值给父类类型变量

多态基础

表现形式:Person p = new Student();

  • 存在自动类型转换

使用条件

  • 有继承关系
  • 有方法重写
  • 有父类引用指向子类对象

好处

  • 使用父类型作为参数,可以接受所有子类对象
  • 体现多态的拓展性与便利
多态调用成员特点
  • 变量调用:编译看左边,运行也看左边

    • Person p = new Student();
      sout(p.name);
      
    • p 中是否初始化了name 决定能否编译成功

    • 运行后实际输出的也是 Person 的 name

  • 方法调用:编译看左边,运行看右边

    • 同上

理解:

  • 用 p 去调用变量和方法,所以在编译时,能否成功看的是父类
  • 用 p 去调用成员变量,调用的是父类的
  • 根据就近原则,公用同一个索引的同名虚方法会使用更近的子类的方法
多态优劣势

优点

  • 在多态形式下,右边的对象可以实现解耦合,便于扩展和维护
    • 只需要把 new Student 改成 new Teacher 就可以实现维护
  • 定义方法时,使用父类型作为参数,可以接受所有子类对象,体现多态的扩展性与便利
    • 例如集合的泛型

弊端

  • 不能调用子类的特有方法,无法编译成功
  • 可以通过类型转换解决 Student s = (Student)p;
  • 转换类型与真实类型不一致会报错
  • 可以用 instanceof 判断
 Person s = new Student();
 if(s instanceof Student){
     Student s1 = (Student) s;
     s1.study();
 }

JDK 14 新特性

Person s = new Student();
if(s instanceof Student s1){
     
     s1.study();
 }

面向对象细节

包就是文件夹。用来管理各种不同功能的 java 类,方便后期代码维护

命名规则

  • 公司域名反写 + 包的作用
  • 全部英文小写、见名知意
  • 全类名(全限定名):com.itheima.domain.Student

使用其他类的规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tWnHQqX5-1668143680534)(/Users/mac/Documents/img/截屏2022-10-25 19.13.47.png)]

  • 使用同一个包中的类时,不需要导包
  • 使用 java.long 包中的类时,不需要导包
  • 其他情况都需要导包
  • 如果同时使用两个包中的同名类,需要使用全类名

导包快捷键:option + command +O

final

修饰方法、类、变量

  • 修饰方法:最终方法,不能被重写
  • 类:最终类,不能被继承
  • 变量:常量,只能被赋值一次,不能修改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YCRfXMV8-1668143680535)(/Users/mac/Documents/img/截屏2022-10-25 19.24.26.png)]

使用场景:

  • 表示一种规则,不想被别人改变
  • String 、不想被继承
  • final a = 10; 只可以被赋值一次,也可以在定义时就给出常量值

常量

实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性

命名规范:

  • 单个单词:全部大写
  • 多个单词:全部大写,单词之间下划线隔开

细节

  • 基本类型:存储的数据值不能改变
  • 引用类型:存储的地址值不能改变,对象内部的可以改变
  • 本质是常量记录的数据无法改变
  • 位置可以在测试类里 main 方法外

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qCUrjCS6-1668143680536)(/Users/mac/Documents/img/截屏2022-10-25 19.55.35.png)]

批量修改同名变量快捷键:control + G

大小写快捷键:shift + command +U

权限修饰符

  • 控制一个成员能够被访问的范围
  • 可以修饰成员变量、方法、构造方法、内部类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPj2lOcg-1668143680537)(/Users/mac/Documents/img/截屏2022-10-25 19.59.29.png)]

  • private :私房钱,只能自己用
  • 默认 :工资,家人都可以用
  • protected:受保护的,外面的儿子也可以用
  • public:公共的

使用规则

实际开发中,一般只使用 private 和 public

  • 成员变量私有
  • 方法公开

特例:如果方法中的代码是抽取其他方法中的共性代码,这个代码一般也私有(grow 扩容),就是只在本类中其他多个方法中使用,外部不调用

代码块

局部代码块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m6QkGtmL-1668143680538)(/Users/mac/Documents/img/截屏2022-10-25 20.09.07.png)]

  • 提前结束变量生命周期、节约内存空间
  • 现在很少使用

构造代码块

写在成员位置的代码块

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RLLuIcyU-1668143680538)(/Users/mac/Documents/img/截屏2022-10-25 20.12.25.png)]

  • 在创建本类对象时,它会优先于构造方法运行
  • 处于成员变量位置
  • 可以吧多个构造方法中的重复内容抽取出来
  • 此技术也渐渐淘汰了,不够灵活

目前使用更多的技术

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YDCHhWxf-1668143680540)(/Users/mac/Documents/img/截屏2022-10-25 20.17.19.png)]

  • 使用 this 调用本类其他构造方法
  • 把重复内容抽象成一个方法

静态代码块(重点)

  • 格式:static{}

  • 特点:需要通过 static 关键字修饰,随着类的加载而加载(最开始时和构造代码块一样),并自动触发、只执行一次

  • 使用场景:在类加载的时候,做一些数据初始化的时候使用

抽象类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qSWGmJiT-1668143680540)(/Users/mac/Documents/img/截屏2022-10-25 21.15.33.png)]

  • 抽象方法子类必须重写
  • 抽象方法所在的类叫抽象类

抽象方法:将共性的方法抽取到父类之后,由于每一个子类执行的内容是不一样,所以在父类中不能确定具体的方法体,该方法就可以定义为抽象方法

抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类

定义格式

  • 抽象方法:public abstract void work(); 无方法体
  • 抽象类:public abstract class Person{}

注意事项

  • 抽象类不能实例化
  • 抽象类不一定有抽象方法,但抽象方法的类一定是抽象类
  • 可以有构造方法
    • 抽象类的构造方法是给子类成员变量赋值用的
  • 抽象类的子类
    • 要么重写抽象类中的所有抽象方法(更多的选择)
    • 要么是抽象类

option + return 可以查看 IDEA 提供的错误修改方法

抽象类和抽象方法的意义

  • 强制子类必须按照此格式重写

  • 合作编程中,统一方法名,提高效率、利于维护

  • 抽象类中如果没有抽象方法,子类不需要重写,也不要求子类必须是抽象类,没有任何要求

  • 可以通过抽象类来必须产生对象

接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L4kMntw2-1668143680541)(/Users/mac/Documents/img/截屏2022-10-26 20.23.36.png)]

  • 接口是对行为的抽象

接口的定义和使用

  • 接口用关键字 interface 来定义 public interface 接口名{}
  • 接口不能实例化
  • 接口和类之间是实现关系,通过 implements 关键字表示public class Person implements 接口{}
  • 接口的子类(实现类)
    • 要么重写接口中的所有抽象方法
    • 要么是抽象类

注意 1 :接口和类是实现关系,可以单实现,也可以多实现。

public class Person implements 接口 1,接口 2{}

注意 2:实现类还可以在继承一个类的共识实现多个接口

接口成员的特点

成员变量

  • 只能是常量
  • 默认修饰符:public static final

构造方法

  • 没有

成员方法

  • public abstract

  • JDK 7 以前只能是抽象方法

接口和类的关系

类和类的关系

  • 单继承、多层继承

类和接口的关系

  • 实现关系,可以单实现,也可以多实现,还可以在继承一个类的时候实现多个接口
  • 多个接口中存在重名情况,只需要重写一次,一次重写相当于全部重写

接口和接口的关系

  • 继承关系、可以单继承、也可以多继承
  • 如果实现的是最下面的子接口,需要重写全部抽象方法

接口拓展

JDK 8 后新增的特性

JDK7 以前:只能定义抽象方法

JDK8 的新特性:接口中可以定义有方法体的方法。(默认、静态)

默认方法:

  • 作用:解决接口升级问题
  • 格式:public default void show(){}
  • 注意事项
    • 默认方法不是抽象方法,所以不强制被重写。重写是去掉 default 关键字
    • public 可以省略, default 不可以省略
    • 如果实现多个接口时,存在重名的默认方法,必须重写

静态方法

  • 格式:public static void show(){}
  • 注意事项
    • 只能通过接口名调用,不能通过实现类名或者对象名调用
    • public 可以省略,static 不可以省略

JDK9 的新特性:接口中可以定义私有方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZmGrda9n-1668143680544)(/Users/mac/Documents/img/截屏2022-10-26 21.42.39.png)]

  • 普通私有方法:private void show(){};
    • 为默认方法服务
  • 静态私有方法:private static void show(){};
    • 为静态方法服务

标记性接口

  • 如果一个接口里面没有抽象方法,表示当前的接口是一个标记性接口
  • 一旦实现,表示当前类的对象就可以被克隆
  • 没有实现,就不能克隆

接口的应用

  • 想让某个 javabean 拥有某个功能,就实现某个接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PyTiE6Q8-1668143680548)(/Users/mac/Documents/img/截屏2022-10-26 21.46.33.png)]

  • 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这就是接口的多态[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uX7I4gPh-1668143680550)(/Users/mac/Documents/img/截屏2022-10-26 21.47.11.png)]

适配器设计模式

设计模式

  • 简单理解:设计模式就是解决各种问题的套路

适配器设计模式

  • 当一个接口中抽象方法过多时,但我们只要使用其中一部分,就可以使用适配器设计模式

  • 解决接口与接口实现类之间的矛盾问题

具体流程:

  1. 创建一个类 InterAdapter 作为中间类
  2. 在中间类中空实现,并将其抽象化,防止实例化
  3. 在需要用的接口的方法时,继承中间类就可以了
内部类

类的五大成员:属性、方法、构造方法、代码块、内部类

Def:在类的里面,再定义一个类

使用场景:发动机和车,发动机是车的内部类

  • 内部类表示的事物是外部类的一部分
  • 内部类单独出现没有任何意义

内部类访问特点

  • 内部类可以直接访问外部类的成员,包括私有
  • 外部类想要访问内部类的成员,必须创建对象

内部类的分类

成员内部类、静态内部类、局部内部类、匿名内部类

成员内部类(了解)

如何书写

  • 写在成员位置的,属于外部类的成员
  • 成员内部类可以被一些修饰符所修饰:private、默认、protected、public、static 等
    • private :只可以在外部类中实例化(用 Object 接收,形成多态)
    • 默认:只能在本包中用
    • protected :在其他包的子类中也可以用
    • public :都可以
  • 在成员内部类里面,JDK16之前不能定义静态变量

获取成员内部类对象

  • 在外部类中编写方法,对外提供内部类的对象
  • 在外界直接创建:Car.Engine e = new Car().new Engine();

成员内部类如何获取外部类的成员变量

  • a
  • this.a
  • Car.this.a

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Fn8QuNt-1668143680563)(/Users/mac/Documents/img/截屏2022-10-27 15.21.28.png)]

静态内部类(了解)

  • 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态需要创建对象

创建静态内部类对象的格式

  • Car.Engine ee = new Car.Engine();

调用非静态方法的格式

  • 先创建对象,用对象调用

调用静态方法的格式

  • Car.Engine.show();

局部内部类(巨没用)

  • 将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量
  • 外界是无法直接使用,需要在方法内创建对象并使用
  • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

匿名内部类(很重要)

  • 匿名内部类本质上就是隐藏了名字的内部类

  • 可以写在成员位置,也可以写在局部位置

什么匿名内部类

  • 整体不是一个类,是 new 出来的对象
  • 真正的类是 {} 里面的内容,与前面的对象是实现或者继承关系

格式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlinYr6t-1668143680601)(/Users/mac/Documents/img/截屏2022-10-27 15.48.23.png)]

应用场景

  • 匿名内部类本质是一个子类或者实现类的匿名对象,使用时可以用作参数来实现多态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Eoin58RR-1668143680602)(/Users/mac/Documents/img/截屏2022-10-27 16.05.38.png)]

补充

  • 匿名内部类也有名字,JVM自动给的

  • 匿名内部类可以用于实现接口的多态

    • Swin s = 匿名内部类
  • 匿名内部类也可以调用方法


拼图游戏项目

GUI:图形用户接口

  • AWT 包
  • Swing 包(更好用)

主界面分析

组件

JFrame:最外层的窗体

  • 设置大小:setSize
  • 可视化:setVisible(true/false)
  • 设计界面标题:setTitle
  • 置顶:setAlwaysOnTop
  • 界面居中:setLocationRelativeTo(null)
  • 设置关闭模式:setDefaultCloseOperation()

JMenuBar :最上层菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q2GRMCep-1668143680603)(/Users/mac/Documents/img/截屏2022-10-27 19.22.35.png)]

JLabel :管理文字和图片的容器

  • 图片:ImageIcon
  • 坐标均为左上角
  • JF 隐藏容器:getContentPane()
  • 取消内部居中:setLayout(null)

事件

  • 事件源:按钮 图片 窗体
  • 事件:某些操作(鼠标点击、鼠标滑入)
  • 绑定监听:当事件源上发生了某个事件,则执行某段代码
    • KeyListener(按下不送、松开)
    • MouseListener(移入、移出、按下、松开、单机)
    • ActionLister(点击、空格)
    • 都是抽象类

JButton 按钮


常用 API

Math
  • final 修饰,最终类,无法继承

常用类方法

  • abs:取绝对值
  • ceil:向上取整
  • floor:向下取整
  • round:四舍五入
  • pow:求幂
System
  • exit:终止虚拟机

    • 0:正常停止
    • 1 :异常停止
  • currentTimeMillis:返回当前系统的时间毫秒值形式

  • arraycopy:数组拷贝

    • 如果都是基本数据类型,必须相同,不存在类型转换
    • 如果都是引用数据类型,子类可以赋给父类

计算机的时间原点:

  • 1970 年 1 月 1 号 08:00
  • c 语言的生日
Runtime
  • 构造方法私有化,通过 get 方法获取对象,不论何时获得的都是同一个对象

  • getRuntime:当前系统的运行环境对象

  • exit:停止虚拟机

  • availableProcessors:Cpu线程数

  • maxMemory:JVM从系统中获取内存大小

  • totalMemory:已获得内存大小

  • freeMemory:剩余内存大小

  • exec:运行 cmd 命令

Object
  • 顶级父类。所有类都直接或者间接的继承于他

  • 他的方法可以被所有子类访问

  • 没有成员变量,所以只有一个空参构造

  • toString:一般会重写,打印对象属性

  • equals:比较两个对象是否相等

    • 没有重写,比较地址值
    • 重写,可以比较属性值
    • 重写要在父类里进行
    • String 的 equals 方法先判断地址是否相同,再判断是否是字符串,若是则比较是否相等,若不是直接返回假
  • clone:对象克隆

    • 被 protected 修饰,使用需要重写

    • 创建一个新对象,并把原对象中的数据拷贝过去

    • User u2 = (User)u1.clone();
      
    • 书写步骤

      • 在 javabean 中重写 Object 中的 clone
      • 让 javabean 类实现 Cloneable 接口
      • 创建原对象并调用 clone

克隆分为浅克隆浅拷贝和深克隆深拷贝

  • 浅克隆引用数据类型克隆地址
  • 深克隆引用数据类型,克隆 new 出的新地址
  • Object 中是浅克隆
  • 使用深克隆需要重写 clone,也可以使用第三方工具 gson

Objects

  • 是一个工具类,提供了一些方法去完成一些功能
  • equals( s1 ,s2):先做非空判断,在比较两个对象
    • 方法底层判断是否为 null,如果为 null ,直接返回 false
    • 如果不是 null,再次调用equals
    • S1,为 Stu,调用 Stu 中的 equals 方法
  • isNull:判断对象是否为 null
  • nonNull:同上
BigInteger

表示近乎无限大的整数

构造方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-04vNbyls-1668143680604)(/Users/mac/Documents/img/截屏2022-11-05 15.50.43.png)]

  • 对象一旦创建,内部记录的值不能发生改变
  • 三种构造方式,只能是整数,否则会报错
  • 使用进制构造时,输出会以十进制输出
  • 静态方法 valueOf 细节
    • 能表示的范围比较小,和 long 相同
    • 对常用数字(-16 ~ 16)进行了优化,先创建好了 BI 的对象,多次获取不需要新建对象
    • 表示常用数字用 valueOf 构造,表示数字大用默认构造方法

常见成员方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kJJ0jTYw-1668143680605)(/Users/mac/Documents/img/截屏2022-11-05 16.21.06.png)]

  • 加add,减subtract,乘multiply,除divide、divideAndRemainder
  • 比较 equals、max、min
  • 次幂 pow
  • 类型转换 intValue
  • max:返回较大的 BI 对象,不会创建一个新对象

底层存储方法

  • 对于计算机而言,其实是没有数据类型的概念的
  • 数据类型时编程语言自己规定的
  • 存储方法
    • 先用 signum 保存符号
    • 然后用 mag 这个整数数组,存储拆分后的一段段数据
    • 上限是 mag 这个数组的最大拼合范围,远超计算机的存储范围,所以 BI 几乎可以存储无限大的整数
BigDecimal

为了表示较大小数和解决计算机中小数的精确存储

计算机中的小数

  • 小数在计算机中的存储不精确

  • float :23 个小数位

  • double:52个小数位

构造方法

  • 通过传递 double 类型的小数来创建对象,该方法有可能是不精确的,不建议使用
  • 通过传递字符串表示的小数来创建对象,该方法是准确的
  • 通过静态方法来获取对象,同 BI 一样,传递常用 long 型数字(0~10)会返回同一个对象
  • 如果表示范围没有超过 double 的取值范围,建议使用静态方法,超出范围建议使用构造方法

常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Avz6z2Al-1668143680606)(/Users/mac/Documents/img/截屏2022-11-05 19.23.53.png)]

  • divide 能除尽无异常,除不尽会报错
  • divide 在使用时需要时,参数需要加入舍入模式,防止报错
  • RoundingMode:舍入模式
    • UP:远离 0 方向取舍
    • DOWN:靠近 0 方向取舍
    • CEILING:向正方向取舍
    • FLOOR:向负方向取舍
    • HALF_UP:四舍五入
    • HALF_DOWN:五舍六入

底层存储方式

  • 遍历得到每一个字符
  • 把每一个字符转换成 ASCII 表中的值存到数组中
  • 理论最大范围时该整数数组的最大范围,实际使用可以看做无限
正则表达式

类名 :Pattern

作用

  • 校验字符串是否满足规则

  • 在一段文本中查找满足要求的内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TQPYgusn-1668143680607)(/Users/mac/Documents/img/截屏2022-11-05 19.59.18.png)]

  • 字符和表达式一一对应 "zz".matches([^abc][^abc])//true
  • 如果要表示两个范围的交集,需要使用 && ,如果只是 & 则知表示该符号本身,其是一个新的范围
  • 用 “.” 需要用 “\\.”
  • 忽略大小写的方式 “?i”

数量词

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D5dBpg7k-1668143680608)(/Users/mac/Documents/img/截屏2022-11-05 20.19.40.png)]

应用

  • 在实际开发中,很少会自己写正则表达式
  • 一般百度一个类似的,自己改成公司要的

小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nR1EoLMI-1668143680611)(/Users/mac/Documents/img/截屏2022-11-05 21.43.54.png)]

爬虫

两个类

  • Pattern:表示正则表达式

    • 通过 compile 获取对象
  • Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取

    • find:拿着文本匹配器从头开始读取,寻找是否有满足规则的子串
      • 如果没有返回 false
      • 如果有返回 true。在底层记录子串的起始索引和结束索引+1
    • group:根据 find 记录的索引,进行字符串的截取

带条件的爬取数据

  • ?表示占位
    • = 表示只截取前半部分
    • :全部截取
    • !:去除后面的部分
  • String regex = "java(?=8|11|17)"

贪婪爬取

  • 在爬取数据的时候尽可能多获取

非贪婪爬取

  • 在爬取数据的时候尽可能少获取

Java 中默认的是贪婪爬取,如果在数量词 + * 的后面加上问号那么此时就是非贪婪爬取

正则表达式在字符串方法中的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d97nucDF-1668143680612)(/Users/mac/Documents/img/截屏2022-11-07 19.47.27.png)]

  • split:返回值是数组

细节:参数时 regex 的方法可以识别正则表达式

老子学不明白,跳过这里了!!!

Date
  • 单纯用来查看时间,很没用

  • 描述时间,精确到毫秒

全世界的时间,有一个统一的计算标准(GMT):同一经线上的时间相同,以本初子午线的时间为准。东加右减,中国东八区,加八个小时

新的时间标准:原子钟

  • 利用銫原子的振动频率计算出来的时间,作为世界标准时间(UTC)

    构造方法

  • 空参构造表示当前时间

  • 有参构造表示指定时间

  • 参数时 long 类型,记得有 L

  • 单位是毫秒值

成员方法

  • S & T
  • 单位是毫秒值
SimpleDateFormat
  • 用于字符串解析 Date 或者格式化形式

  • Date 的格式不方便阅读和使用,所以引入了本类

  • 作用

    • 格式化:把时间变成我们喜欢的格式
    • 解析:把字符串表示的时间变成 Date 对象

构造方法

  • 他创建对象,创建的是一种格式

  • 空参构造:使用默认格式

  • 有参构造:使用指定格式

常用方法

  • format(Date):格式化
  • parse:解析

常用模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oqtb2AoZ-1668143680613)(/Users/mac/Documents/img/截屏2022-11-07 21.50.10.png)]

细节:比较时间时,先解析再 get ,最后用毫秒值比较

Calendar
  • 用来对时间进行修改和计算

  • 代表了系统当前时间的日历对象,可以单独修改、获取事件中的年月日

  • 细节:Calendar 是一个抽象类,不能直接创建对象

获取日历对象方法

  • 静态方法:getInstance
  • 会根据系统的不同时区来获得不同的日历对象
  • 时间中的信息存储在 int 数组里
  • 月份的范围是(0 ~11)
  • 星期:1 代表周日,7 代表周六

常用方法

  • getTime:获取日期对象
  • setTime:设置日期对象
  • getTimeInMillis:拿到时间毫秒值
  • setTimeInMillis:设置时间毫秒值
  • get:取日历中的某个字段信息,建议使用静态变量,提高可读性
    0. 纪元
    1. 一年中第几周
    2. 一个月中第几周
    3. 日期,一个月中第几天
  • set:修改日历的某个字段信息
  • add:为某个字段增加或者减少指定的值

使用细节

  • 查表法:让数据跟索引产生关系
    • 星期可以自己定义一个方法,通过字符串数组,来转换
  • 修改月份和星期时记得美国人的习惯,增加和减少存在进位
JDK8 时间类

优点

  • 代码层面
    • 简单,提供了判断的方法和计算时间间隔的方法
    • 不需要再换算成毫秒值再比较
  • 安全层面
    • JDK7 在多线程环境下会导致数据安全问题
    • JDK8 获得的时间日期对象时不可变的
Date类
  • ZoneId:时区
  • Instant:时间戳(标准时间)
  • ZoneDateTime:带时区的时间

ZoneId 时区

  • Asia/Shanghai(常用)
  • Asia/Chongqing

常用方法

  • 静态方法 getAvailableZoneIds:获得 java 中支持的所有时区
  • 静态方法 systemDefault:获得系统默认时区
  • 静态方法 of:获取一个指定时区

Instant 时间戳

构造方法

  • 静态方法 now:获取当前时间的对象
  • 静态方法 ofXxxx:根据(秒、毫秒、纳秒)获取 Instant 对象

常用方法

  • atZone:指定时区
  • isXxx:判断系列的方法
    • After\Before
  • minusXxx/plusXxx:更改时间系列的方法
    • 对象是不可变的,修改返回的是新对象

ZoneDateTime

构造方法

  • now、of

常用方法

  • withXxx:修改时间系列
  • minux、plus

SimpleDateFormat 日期格式化类

DateTimeFormatter

  • 用于时间的格式化和解析

常用方法

  • 静态方法 ofPAttern:获取格式对象
  • format:按照指定方式格式化

Calendar 日历类
  • 可以单独的操控年月日

  • LocalDate:年月日

  • LocalTime:时分秒

  • LocalDateTime:年月日时分秒

构造方法

  • now、of

常用方法

  • get、with、minux、plux
  • isBefore、isAfter
  • XxToXx:实现大转小

工具类
  • Duration:用于计算两个时间间隔(秒、纳秒)
  • Period:用于计算两个日期间隔(年月日)
  • ChronoUnit:用于计算两个日期间隔(功能最全最好用)

常用方法

  • between:用第二个减第一个
包装类
  • 基本数据类型对应的引用数据类型
  • 类中的成员变量 value 记录数据的值

作用

  • 因为多态的存在,方法的参数可以是所有 Objec 的子类,所以不可以是基本数据类型,可以是引用数据类型
  • 集合中只可以存储引用数据类型

Integer

JDK5 以前(掌握)

构造方法

  • 参数整数字符串都可以
  • new
  • 静态方法 valueOf
  • 两种构造方法区别
    • new 出的是新对象
    • valueOf 表示相同的较小数据是同一个对象(-128 ~127)节约内存空间

如何计算

  • 先通过 intValue 进行拆箱
  • 计算
  • 在装箱

JDK5

  • 提出了一个机制:自动装箱和自动拆箱

  • Integer i = 10;

  • int i2 = i;

成员方法

  • toBinaryString:得到二进制
  • toOctalString:得到八进制
  • toHexString:得到十六进制
  • parselnt:把字符串类型的整数转成 int 类型的整数

细节

  • java 是一种强类型语言:每种数据在 java 中都有各自的数据类型,在计算时,不是同一种类型,无法直接计算
  • 在类型转换的时候,括号中的参数只能是数字不能是其他,否则代码会报错
  • 八种包装类中除了 Character 都有对应的 parseXxx 的方法,进行转换

算法

查找算法

顺序查找

很简单不多说了


二分查找/折半查找

优势:提高查找效率

前提条件:数组中的数据必须是有序的

核心逻辑:每次排除一般的查找范围

如何实现?

  • 定义两个索引:min max
  • 然后不断更新索引

差值查找

  • 通过加权来改进二分查找

  • mid = min + (key-Valueofmin)/(Vmax=Vmin)*(max-min)

斐波那契查找

  • 通过黄金分割比来改进二分查找
  • mid = min + 黄金分割点左边长度-1

分块查找

原则

  • 块内无序,块间有序
  • 块数数量一般等于数字的个数开根号

核心思路:先确定要查找的元素在哪一块,然后在块内挨个查找

具体思路

  • 创建块类:最大值、起始索引、结束索引
  • 创建索引表:存储块对象

分块查找的扩展

  • 块间不满足一定的大小顺序

  • 分块之间没有交集

  • 块类中存储范围

分块思想

哈希查找

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X2rQgsU6-1668143680615)(/Users/mac/Documents/img/截屏2022-11-09 21.18.01.png)]

排序算法

冒泡排序

  • 两两比较,依次交换,多次排序
  • 一共进行数组长度 -1 次排序

选择排序

  • 用 0 索引和后面的元素比较,保证第一个是比较所有元素中最小的

插入排序

  • 将 0 索引的元素到 N 索引的元素看作是有序的,把后面的所有元素当成是无序的。遍历无序的数据,将遍历到的元素插入到有序序列中的适当位置,如遇到相同数据,插在后面
  • 遍历的顺序是从后往前
  • 插入通过交换来实现
递归算法
  • 方法中调用方法本身

注意点

  • 递归一定要有出口,否则就会出现内存溢出

作用

  • 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来解决
  • 只需要少量的程序就可以描述出解题过程所需要的多次重复计算

书写递归核心

  • 找出口:什么时候不再调用方法
  • 找规则:如何把大问题变成规模小的问题

心得:方法内部再次调用方法时,参数必须要更加靠近出口

快速排序

第一轮:把 0 索引的数字作为准数,确定基准数载数组中的正确位置,比基准数小的在左边,大的在右边

  • end 指针找比基准数小的数据
  • start 找比基准数大的数据
  • 找到一组就交换位置
  • 当start和end重合时,基准数归位
  • 一定要先找 end 指针,再找 start 指针
Arrays

操作数组的工具类

常用方法

  • toString:把数组拼接成一个字符串
  • binarySearch:用二分查找查找元素
    • 查找元素存在返回正确的索引值
    • 查找元素不存在返回 -插入点 -1
  • copyOf、copyOfRange:拷贝数组
    • 包头不包尾、包左不包右
  • fill:填充数组
    • 全部覆盖
  • sort
    • 一个参数:按照默认方式进行数组排序
    • 两个参数:按照制定规则排序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kUeVQe2I-1668143680616)(/Users/mac/Documents/img/截屏2022-11-10 16.10.51.png)]

Lambda 表达式

简写匿名内部类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXZufSte-1668143680617)(/Users/mac/Documents/img/截屏2022-11-10 16.20.23.png)]

函数式编程思想

  • 面向对象:先找对象再找方法
  • 忽略面向对象的复杂语法,强调做什么,而不是谁去做
  • Lambda 表达式就是函数式思想的体现

JKD8 新形势

() -> {
  
}
  • ():方法的形参
  • { } :方法体

基本作用

  • 用来简化匿名内部类的书写

使用前提

  • 只能简化函数式接口的匿名内部类的写法
  • 函数式接口:有且只有一个抽象方法的接口叫做函数式接口,接口上方可以加 @FuctionalInterdace 注解

好处

  • Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码,他可以写出更简洁、更灵活的代码,作为一种更紧凑的代码风格,使 java 语言表达能力得到了提升

Lambda 表达式省略写法

核心:可推导,可省略

省略规则

  • 参数类型可以省略不写
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略
  • 如果 Lambda 表达式的方法只有一行,打括号分号,return 可以省略不写,需要同时省略

集合进阶

集合体系结构

两类

  • Collection:单列集合
    • 一次只能添加一个
  • Map:双列集合
    • 一次添加一对

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bgROZoCo-1668143680617)(/Users/mac/Documents/img/截屏2022-11-10 20.47.57.png)]

  • 红色的是接口
  • 蓝色的是实现类
  • List 系列集合:添加的元素是有序(存和取的顺序是一样的)、可重复、有索引
  • set 系列集合:添加的元素是无序(存和取的顺序可能不同)、不重复、无索引
Collection

单列集合的顶层接口,他的功能是全部单列集合都可以继承使用的

常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZ3WrjcT-1668143680618)(/Users/mac/Documents/img/截屏2022-11-10 20.54.48.png)]

  • 大部分都很熟悉
  • 添加元素:往 List 系列集合中添加数据,返回值永远为 true,因为 List 系列是允许元素重复的。Set 系列如果添加元素重复,返回 false
  • 删除元素:因为 Collection 里面定义的是共性的方法,所以不能通过索引删除,同时该方法会对删除结果返回布尔值
  • 判断元素是否包含:contains 方法底层是依赖 equals 方法进行判断是否存在的。所以如果集合中存储的是自定义对象,也想通过 contains 方法来判断是否包含,那么在 javabean 类中,需要重写 equals 方法

注意点

  • Collection 是一个接口,我们不能直接创建他的对象
Collection 的遍历

一、迭代器遍历

特点:不依赖索引

类名:Iterator,是集合专用的遍历方式

构造方法

  • iterator:默认之乡当前集合的 0 索引

常用方法

  • hasNext:判断当前位置是否有元素,并返回布尔值
  • next:获取当前位置的元素,并将迭代器的对象移向下一个位置

细节注意点

  • 报错 NoSuchElementException:强行输出超出索引范围的元素
  • 迭代器遍历完毕,指针不会复位
  • 循环中只能用一次 next 方法
  • 迭代器遍历时,不能用集合的方法进行增加或者删除,实在要删除可以用迭代器的 remove 方法进行删除,如果要添加,暂时没有办法
  • next 的本质是获取元素,移动指针,所以 hasNext 和next 要配套使用,一一对应

二、增强 for 循环

特点

  • 增强 for 循环的底层就是迭代器,为了简化迭代器的代码书写的
  • 他是 JDK5 之后出现的,其内部原理就是一个 Iterator 迭代器
  • 所有的单列集合和数组才能使用增强 for 进行遍历

格式

//list.for
for(String s:list){
  sout(s);
}
  • s 是临时变量用来存储遍历到的元素,修改 s 不会改变集合中的数据

三、Lambda 表达式遍历

forEach底层原理

  • 其实也会自己遍历集合,依次得到每个元素
  • 把得到的每个元素传递给 accept 方法
  • s 一次表示集合中的每一个数据

Lambda 格式

coll.forEach(s -> System.out.print(s+" "));

匿名内部类格式[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Znz7e8WU-1668143680618)(/Users/mac/Documents/img/截屏2022-11-10 23.22.32.png)]

遍历方法比较

  • 迭代器:在遍历过程中,需要删除元素,请使用迭代器
  • 增强 for、Lambda:仅仅想遍历,使用这两个代码更加简洁
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值