一、注释

​ 单行注释 // 快捷键 ctrl+/

​ 多行注释 多行注释不能嵌套

​ 文档注释 JavaDoc

1.标识符定义

​ 大驼峰命名 (类名) 例如SelectById

​ 小驼峰 (方法名 变量) 例如 selectById

​ 一般全小写的命名是数据库的命名

二、数据类型

​ 对所有的数据进行分类(都有默认值)

1.数字

1.1 整数

byte[-128,127] short int long —–0

1.2 小数

float[单精度浮点数] double[双精度浮点数] —-0.0

1.3 字符

char 单子字符或汉字 —空

‘A’ ‘a’ ‘好’ ‘牛牛’ ‘鸀’

1.4 布尔型

boolean 只有两个取值 —–false

true false

1.5 String(字符串)

“sadasdasd撒大苏打飒飒大”

2.引用数据类型:

默认值都是 null

常量: 一个固定不变的值

2.1 变量

语法一: 先定义 后赋值

语法二: 定义同时赋值

语法三: 同时定义多个变量

3. 变量的分类

3.1 成员变量

1.定义的位置类里面,方法的外面

2.全局都可以使用

3.不赋值也是可以使用的 有默认值

3.2 局部变量

1.定义在方法内部或者代码块里面

2.只能在当前的方法 或者代码块的内部使用

3.必须先赋值后使用

注意事项

局部变量可以和成员重名,一般不推荐这么写。

在使用的时候 优先使用局部变量,其次才使用成员变量

三、数据的类型转换

​ 数据类型直接的相互转换

1.自动转换

多个不同类型的数据 进行数学运算的时候 进行自动提升

2.强制转换

把大的数据类型 使用一个小的类型来接收

语法:小数据类型 变量名 = (小数据类型)大类型值/大类型变量名;

注意:使用float或者Double精度会缺失需要用到BigDecimal方法

四、运算符

1.数学运算

1.1 加减乘除

+的功能 除了数学运算,可以拼接字符串

自增 自减 对于一个变量的操作

++ 在前 :先自增 再使用值(使用的是自增以后的值)

++ 在后:先使用值 再自增(使用的是自增之前的值)

1.2 赋值运算

+= -= *= /= %=

使用的场景,把运算完成以后的结果赋值给本身

1.3 比较运算

< >= <= == != instanceof

instanceof:判断一个对象,或者实例 常量是否属于一个类型

1.4 三目运算

语法: x ? y : z;// 表示如果x为true,执行y,x为false则执行z。

x:比较运算的结果 boolean类型的变量

五、位运算

开发很少用,效率高,可读性差

1.逻辑运算

概念,综合多个比较的结果得出一个统一的概念

&——并且

|——或者

!——取反

具有短路效果,可能效率要高一些

&& 和 &最终的结果是一致

|| 和 |最终的结果是一致

六、选择结构

改变代码的执行流程

1.if 条件语句

1.1 语法一

1
2
3
4
5
if(①判断结构){

②//功能语句

}

如果 ①最终结果为true 就去执行 ②的功能语句

如果 ①最终结果为false 就不执行 ②的功能语句

1.2 语法二:互斥

1
2
3
4
5
6
7
8
9
if(①判断结构){

②//功能语句

}else{

③//功能语句

}

如果 ①最终结果为true 就去执行 ②的功能语句,否则就去执行③功能语句

1.3 语法三:多条件判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if(①判断结构){

②//功能语句

}else if(③判断结构){

④//功能语句

}else if(⑤判断结构){

⑥//功能语句

}else if(⑦判断结构){

⑧//功能语句

}

2.switch 循环语句

使用场景: 一般用于有几种固定的取值情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
switch(变量){

case 值1:

功能语句1

功能语句2...

break;

case 值2:

功能语句1

功能语句2...

break;

case 值3:

功能语句1

功能语句2...

break;

default语句

break;

}

2.1 default

相当于条件语句中else,所有的case匹配不上执行

2.2 break

特点结束当前的匹配功能语句。

3.while循环语句

特点结束当前的匹配功能语句。

循环结构:重复的去执行一段代码

床–食堂–游戏

家–旅游–洗脚–公司

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while(①判断语句){

②//功能代码

}



①--true--②

①--true--②

①--true--②

①--false 停止循环

4.dowhile循环语句

基本语法

1
2
3
4
5
6
7
do {

3.循环体(重复干的事)

4.循环控制(根据条件判断是否要写)

} while (2.条件判断);// 注意分号

第1次:1. 初始化条件语句 => 3. 循环体 => 4. 循环控制语句

第2次:2.条件判断语句 => 3. 循环体 => 4. 循环控制语句

第3次:2.条件判断语句 => 3. 循环体 => 4. 循环控制语句

5.For循环

1
2
3
4
5
for(①初始化条件语句; ②条件判断语句; ③循环后语句) {

④循环体

}

第一次循环: ①—②–true–④—③

第二次循环: ②–true–④—③

第三次循环: ②–true–④—③

第四次循环: ②–true–④—③

第n次循环: ②–false —终止循环

6.循环控制语句

break: 表示结束当前层循环

continue:跳过本次循环

return:结束当前方法

七、学习数组的标准

1.如何定义一个数组(语法)

1.1 语法一

定义一个空数组(动态创建)

数据类型[] 名字=new 数据类型[长度];

定义一个指定长度的空数组

1.2 语法二

定义一个数组并赋值(静态)

数据类型[] 名字={值1,值2,值3,值4….}

2.数组的取值与赋值

2.1 赋值的语法

数组名[索引位置]=值;

2.2 取值的语法

数组名[索引位置]

3.注意

1.取值与赋值不能超出索引范围

2.数组一旦定义长度不能更改

3.数组的遍历(把数组里面的每一个数据读取出来)

八、方法

和主方法差不多 ,主方法main,有特殊性程序运行的唯一入口

其他的方法,普通方法

方法:就是功能的封装

1.方法如何定义

语法:

[修饰符] 返回值类型 方法名([形参1,形参2,..]){

//方法体,这个方法的功能逻辑代码

}

void:返回值类型之一,没有返回值[占位符,为了满足语法需要]

2.方法调用

程序只会执行main方法里面的内容

只能在main里面去调用普通方法

2.1 方法名()

调用者和被调用者,必须在同一个类里面,两者要么都有static修饰,要么都没有static修饰

2.2 类名.方法名()

被调用的方法有static修饰 类名:被调用方法所在类的类名【必须掌握,用的非常多】

2.3 对象名.方法名()

被调用的方法没有static修饰【暂时不管】【必须掌握,用的非常多】

程序运行的唯一入口

​ 1.main 执行的顺序 还是从上到下依次执行,遇到调用方法的时 候,把方法内部的逻辑全部执行完成以后,再继续往下执行
2.方法的每一次调用都是完全独立的

3.形参

形式参数,注重只是传出的参数类型,方法在设计的时候不确定的值 (由用户在调用的时候才传入的值)

方法名(数据类型 变量名,数据类型 变量名,….)
*

4.返回值类型

4.1 void

​ 没有返回值,void只是占位满足语法需求

4.2数据类型(学习过的所有数据类型):

​ 方法执行结束以后 返回一个指定类型的 数据

return 返回值; 返回数据的语法

把方法内部的执行结果返回给方法的调用者

5.调用者对于方法的返回值有哪些处理方式?

5.1 直接打印

5.2 使用变量接收

方法的重载

把同一类的方法,一般名字都保持一直。

Overload[重载] – Override[覆写]

方法名一致,形参列表不同【个数,类型,类型顺序】

九、数组的存储模型

1.1 栽

​ 存储的变量名 基本数据类型的值

1.2 堆

​ 引用数据类型的值

十、方法调用的时候

​ 基本数据类型传递的值得本身,引用数据类型传递的是地址的引用

十一、可变参数

​ 语法在定义方法的时候 可以使用数据类型

​ 可变参数的本质还是数组

​ 注意:在定义方法的时候 只能有一个可变参数,并且放在方法形参的末尾

十二、for—each 增强for循环

本质还是for

1
2
3
for(数据类型 变量名 :数据源){

}

变量名:就是循环以后数组里面的每一个值

数据类型:数组里面装的是什么类型

特点:foreach 没有下标

以后在使用的过程中,什么时候使用for循环 什么时候使用for–each

如果要用到索引,必须要使用普通for循环

十三、javadoc

System

static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

将指定源数组中的数据从指定位置复制到目标数组的指定位置。

src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目的地数据中的起始位置。
length - 要复制的数组元素的数量。

十四、构造方法

1.什么是构造方法?

构造方法主要是用来创建对象

构造方法的语法

要求:没有返回值类型,方法名和类名保持一致(包括大小写)

[修饰符] 类名([形参]){
*

}

1.2构造方法的作用

1.主要使用来创建对象的,没有可用的构造方法 就不能创建对象

2.创建对象的时候赋值

1.3构造方法的注意点

1.每一个类都有一个隐式公共无参数的构造方法–学习了反射就能够证明

2.如果类里面显示的写了构造方法,隐式的无参数的构造方法就不存在了—–如果要显示的添加构造方法,一般建议把无参数的构造方法也加上

1.4问构造方法和方法有什么区别?

构造方法 方法

1.返回值类型 无 有

2.方法的名字 必须和类名一致 无特殊要求

3.static 不能修饰 可以修饰

4.调用方式 new 类名./对象名.

5.功能 创建对象 普通工具

public Account(){} 是

public void Account(){} 不是【不建议这么去定义普通方法】

十五、匿名对象

对象的生命周期:

开始—被创建的时候(new)

结束—被垃圾回收器回收的时候,失去引用的时候

对象的生命周期:

人的生命周期:

开始—出生

结束—死亡(心脏,脑死亡,失踪,被所有人遗忘的时候)

十六、继承

public class 类名 extends 父类的类名{}

1.可以继承哪些内容?

属性

方法

2. 受哪些因数影响?

非私有化的成员变量和方法

构造方法不能被继承

3. 继承的特点

1.java里面3类只能单继承,一个类只能一个直接父类

2.java支持多层级继承

3.如果一类没有显示的去继承任何一个类,这个类继承于Object

Object:超类,所有类的直接或间接父类

十七、方法覆写-Override

1. 什么情况下需要方法的覆写?

当父类方法的功能无法满足子类的需要,需要方法覆写

2. 要求

1.子类方法的权限修饰符,大于等于父类权限修饰符

2.子类方法的返回值类型必须要小于等于父类方法的返回值类型

3.方法.名一致

4.形参类型一致

方法名+形参列表=方法签名

2.1 一般情况下

方法的覆写都是把父类的方法直接copy过来,更改里面的方法体就ok

2.2 方法调用的整体大纲

一般来讲,在调用方法的时候有限找子类方法,如果子类没有,就去找父类的方法

十八、super

1. 作用

1.可以在子类构造方法里面调用父类的构造方法,必须写在第一行

2.当子类里面的方法或者属性和父类的方法或者属性重名的时候,区分二义性

2. 特点

子类的构造方法里面,默认都是在调用父类的无参数构造方法

3. super和this的区别

this:就是指当期对象—-this就是对象

super:指的是父类的成员(属性,方法),但是不是父类对象,不持有父类对象的地址引用

十九、抽象类

抽象类定义的语法

把由abstract 修饰类 叫做抽象类

1.1 抽象类里面有哪些成员

普通方法

抽象方法

构造方法:有构造方法,但是不能创建对象,由protected修饰的,主要是用于继承的时候子类调用;

成员变量

1.2 抽象方法

[父类定义了一些规范]

由abstract 修饰的方法叫做抽象方法,方法的没有方法体

子类继承父类以后,必须要去覆写父类的所有抽象方法

只能出现在抽象类中

abstact 抽象的 出现在修饰符与 返回值之间

抽象类中可以有变量 方法 抽象方法(可有可无)

1.3 目前这个知识点

1.必须知道抽象类的定义语法

2.抽象里面可以定义那些成员

3.抽象方法不能创建对象

4.子类必须要去覆写父类的所有抽象方法

二十、接口

1. 接口的作用

1.用来定义规范

2.解耦

2.后面这些功能体现

1.jdbc 定义的规范

2.servlet 也是一套接口 定义了规范

3.接口的语法

接口和类 是同一个级别,但是完全不同的两种类型

interface 接口名字{

}

接口的里面可以有哪些成员:

成员变量

抽象方法【百分之90接口只是提供抽象方法】

4. 在jdk的1.8以后新增很多新特性

1.可以有静态方法 -由static修饰的

2.可以有默认方法 -由default修饰的

实现的语法:

class 类名 implements 接口名{

//必须要去覆写所有接口的抽象方法

}

二十一、覆写的应用

父类方法功能无法满足子类需求的时候 ,去覆写父类方法

方法覆写的调用规则

优先找子类的方法,如果子类没有,再找父类的方法

当继承的父类的某个方法,不满足现有的需求,那么可以在子类中进行重写

方法的重写:将父类的方法直接继承到子类中,主要改写,该方法体的内容

方法重写的条件:必须在继承关系中去实现

方法重写:修饰符(子类中修饰符权限更大) 返回值为void是,父类和子类中的返回值类型一致 如果父类中的返回值不为void类型

​ 那么子类中的返回值应该小于等于父类中的返回值为八大类型,那么子类的返回值应该与父类的返回值一致

自定义类型比较:进行排序使用

自定义类型比较的实施:在自定义类中重写equals方法

二十二、Object

boolean equals(Object obj) 指示一些其他对象是否等于此。[非常重要]

protected void finalize() 当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。 –回收垃圾

1. final finally finalize -区别?

Class<?> getClass() 返回此 Object的运行时类。

int hashCode() 返回对象的哈希码值。 –对象存储的在内存里面的位置值

== 是用来比较基本数据类型的值是否相等

如果用于引用数据类型的比较,比较的是两个对象的地址值

注意:特殊情况除外,例如String 以及八大基本数据类型对应的包装类除外

2. 讨论

比较两个对象,到底是应该比较两个对象的地址,还是比较两个对象的里面存储的数据?

例如 两张身份证长得一模一样 姓名 性别 出生年月 身份证号码 图片

在java领域里面 引用数据类型比较应该使用equals方法—Object[能够比较里面存储的数据]

注意:默认 equals方法底层还是 == 在比较两个对象地址值是否相等,

覆写equals方法比较两个对象里面的值是否相等。

3. 思考:面试题

说一说 == 和 equals 的区别?

自己先尝试整理一个稍微专业一点的回答话术。

== 用于比较基本数据类型的两个值是否相等,如果用于比较引用数据类型,比较的是两个对象地址值

equals:用于比较两个对象里面存储的数据是否相等,但是equals底层还是==,所以我们在使用的时候要腹泻equals方法

二十三、多态

1. 例子

一个人 是 人 Person p = new Person()

一头猪 是 猪 Pig pig = new Pig()

一个人 是 动物 Animal a = new Pserson()

一头猪 是 动物 Animal a2 = new Pig()

一个人 是 猪(错误) Pig p = new Person()

一头猪 是 人 (错误) Person p = new Pig()

2. 官方

编译时类型和运行时类型不一致的情况叫做多态

3. 坊间

使用父类类型接收子类对象,或者使用接口 接收接口的实现类对象–多态

使用多态的时候,方法的调用的问题:

方法覆写以后,方法的调用顺序是不变的

Super–父类相关

super用在子类中的–只有在子类中才会区别,到底是使用的父类的属性/方法还是使用子类中的属性/方法

super可以直接打印吗?

super代指的父类(没有持有父类的对象(没有创建))this可以直接打印,持有当前对象

Super():只能放在子类中的构造方法的第一行,子类创建对象的时候,先要调用父类的构造方法,是为了可以继承的相关属性和方法

二十四、final

​ 也是一个修饰符,翻译过来是最终的

成员变量 局部变量 构造方法 普通方法 内部类, 类

1. 可以修饰内容

类,成员变量 局部变量 普通方法 内部类

2. 被final修饰以后有什么效果

类:final修饰的类不能被其他类继承 开发中有没有类不允许继承? String-八大基本数据类型对应的包装类

成员变量:final修饰的成员变量不允许更改值

局部变量:一旦赋值就不能个更改

普通方法:final修饰的方法不能够被覆写

二十五、static

成员变量:被所有对象所共享 应用场景:火车站卖票,对象之间应该共享的属性

方法:修饰方法的时候仅仅只是为了方便调用,使用类名就可以直接调用,一般工具类的方法适合定义为static修饰的方法 例如 Arrays

面向对象阶段:如果要操作非static的成员变量的时候,不考虑static

静态方法不能操作非静态的成员变量

1. static:修饰的成员正确的使用方式

1.1 修饰成员变量

类名.属性名

修饰的方法:

类名.方法名();

1.2 方法的调用

1.方法名(); 在同一个类里面,要么都被static修饰,要么都没有被static修饰

2.类名.方法名(); 被修饰的方法被static修饰

3.对象.方法名(); 被调用的方法没有被static修饰

2. static修饰的成员的称呼

类名 位置 是否有static 生命周期开始 生命周期结束
类变量 类中 类被加载的时候 类被卸载的时候
实例变量 类中 创建对象的时候 对象失去引用
局部变量 方法代码块中

二十六、匿名内部类

Usb这个接口不能new 创建对象

1. 正常的顺序:

1.新建一个类 实现Usb这个接口

2.创建实现类对象,并调用接口方法

2. 匿名内部类使用场景:

1.接口的里面的抽象方法并不多(1-3个)

2.对于接口的实现类对象不会重复使用(只是需要一个对象用一次)

3.不想再去多创建一个实现类文件

二十七、代码块

由 { 代码 } 包裹起来的代码 叫做代码块

从代码块存放的位置来讲把代码块分为3类:

1. 构造代码块

写在类里面的代码块,叫做构造代码块,创建对象的时候执行【没啥用】

因为构造代码块编译以后里面的内容就会放到构造方法中,所以构造代码块随着对象的创建而去执行

2. 静态代码块

放在类里面由static修饰的代码块【以后会使用】

随着类的加载而执行一次 应用场景

【加载配置文件,应为配置文件只是加载一次】

3. 局部代码块

放在方法的内部,主要作用用于区分方法功能性【没啥用】

随着方法的执行而执行

二十八、面对对象整体架构

面向过程关注过程每一个实现的步骤

面向对象关注的结果把没有给步骤交给其他类和方法处理

面向对象编程:万物皆可对象将世间万物看不见的抽象成对象

对象:数据的集合,包含了属性和方法

核心内容:封装-继承-多态

1. 封装思想

为了使成员变量更加安全和私密,给成员变量加上private进行私有化。

–先加上SetName GetName –pubilc

2. 继承思想

2.1 继承的好处

减少代码量/减少重复的代码

2.2 继承之后的效果

子类可以直接使用父类的属性/方法 无需再定义

2.3 继承的优点

如果父类中的属性/方法,如果使用了private修饰,那么子类是无法继承的

子类无法同时继承多个类 但是继承支持多层继承

3. 多态思想

创建了子类对象 使用父类来 接收 -这种场景称为多态

官方说法:编译时类型与运行时类型不一致的情况叫做多态

编译时类型:等号的左边,编译阶段编译器看成的类型

运行时类型: 等号右边,运行阶段,对象真实的类型

二十九、包装类

1.什么是包装类

答:就是针对8大基本数据类型,提供的类的表示形式
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

例如 上面的就是基本数据类型对应的包装类,Byte 描述的就是 [-128,127] 这一类事物

2.为什么要提供包装类

答:基本数据类型 只能单纯的表示一个数字或者值,类除了可以表示一个值 还可以提供方法

例如 byte 只能表示 [-128,127]的数字,但是包装类除了可以表示 [-128,127]的数字 提供的有对应一些方法

3.包装类和基本数据类型有哪些不同

3.1

基本数据类型 有各自默认值

包装类 默认值是 null

3.2

基本数据类型 不能够去调用方法

引用数据类型可以调用方法

三十、包装类装箱与拆箱

装箱:把基本数据类型赋值给一个对应的包装类的过程

自动装箱拆箱只支持 基本数据类型和其对应的包装类

拆箱:把一个包装类的类型 赋值给一个对应的基本数据类型的过程

享元模式:设计思想和常量池有点类似 轻量级框架设计

享元模式:把[-128,127]之间所有的数组都缓存起来,方便节约内存重复使用

包装类:享元模式 提前缓存好

String:常量池 用的时候先去找,没找到再缓存

结论:比较两个包装类型的数字是否想的还是应该使用equals

三十一、String

表示字符串的

“abc” 和 new String(“abc”)都是String的对象

构造方法:

String() 初始化新创建的 String对象,

使其表示空字符序列。 相当于 “”

三十二、String 的常用方法

char charAt(int index) 返回 char指定索引处的值。

String concat(String str) 将指定的字符串连接到该字符串的末尾。

boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结尾。

int indexOf(int ch) 返回指定字符第一次出现的字符串内的索引。

boolean isEmpty() 返回 true如果,且仅当 length()为 0 。

int length() 返回此字符串的长度。

String replace(CharSequence target, CharSequence replacement)

将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。

String[] split(String regex) 将此字符串分割为给定的 regular expression的匹配。

String substring(int beginIndex) 返回一个字符串,该字符串是此字符串的子字符串。

String substring(int beginIndex, int endIndex) 返回一个字符串,该字符串是此字符串的子字符串。

char[] toCharArray() 将此字符串转换为新的字符数组。

String toLowerCase() 将所有在此字符 String使用默认语言环境的规则,以小写。

String toUpperCase() 将所有在此字符 String使用默认语言环境的规则大写。

String trim() 返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。

三十三、== 和 equals区别?

对于引用数据类型:

== 比较的两个对象的地址值

equals 比较的是两个对象里面存储的数据

三十六、String常量池

按照对象的存储特点,每一个对象在堆里面的引用地址都不一致,如果使用== 比较都应该是false

(1)当第一次使用String str = “A”; 的方式赋值,会将该字符串值【对象】放入到常量池
(2)当再次使用String str = “A”; 的方式会先检查常量池是否有”A”值,
① 如果存在直接引用
② 如果不存在,会创建”A”放入常量池
(3)字符串拼接
① 常量方式拼接,并直接使用赋值符号赋值,会检查常量池
② 变量方式拼接,不会检查常量池【注意】

结论:String的比较还是应该使用equals不能使用==

三十七、String StringBuilder StringBuffer 都是字符串

构造方法

StringBuffer(String str) 构造一个初始化为指定字符串内容的字符串缓冲区。

StringBuilder,StringBuffer

StringBuffer append(Object obj) 追加 Object参数的字符串表示。

【可以动态的拼接字符串】

使用场景:一般用于有大量的字符拼接的情况,例如生成 csv格式对账单{80-150w}

String 的拼接效率太低了

等到线程那一天学习:

StringBuffer:是线程安全的 效率稍低 使用单线程

StringBuilder:线程不安全的 效率最高 使用多线程

三十八、Math

1. 字段 PI

static double random() 返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。

方法都不怎么常用,在某些特定领域用的就非常多(小猿搜题)

BigInteger(基本不用-了解)

可以用来去表示比Long更大的数字

2. BigDecimal【重点】

|-可以用来去表示精确浮点数

(double和float都不能精确的表示一个小数)

2.1 构造方法:

BigDecimal(String val) 将 BigDecimal 的字符串表示形式转换为 BigDecimal。

形参为什么不给一个double去表示一个精确的小数

数字常用的操作 + - * / 都是通过方法来完成

1
public BigDecimal add(BigDecimal augend)  // 求和

返回一个 BigDecimal,其值为 (this + augend),

1
BigDecimal divide(BigDecimal divisor)      //除法

返回一个 BigDecimal,其值为 (this / divisor),

1
BigDecimal multiply(BigDecimal multiplicand)  //乘法

返回一个 BigDecimal,其值为 (this × multiplicand),

1
BigDecimal subtract(BigDecimal subtrahend)  //减法

返回一个 BigDecimal,其值为 (this - subtrahend)

2.2 BigDecimal一般用于哪些行业和领域?

BigDecimal一般需要表示一些精确的小数的时候都需要使用它,涉及到钱相关的,建筑行业

关于数学数字处理 不是一味地四舍五入

数字的舍入方式: 银行卡的余额 一般是小数点后面 2位

金融领域里面:利息和手续费

利息 –例如312.359—312.35

手续费–例如0.231—-0.24

三十九、java里面随机数获取方式

1. Math

static double random() 返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。

2. Random

int nextInt() 返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。

生成一个 int 范围内的随机数

int nextInt(int n) 返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
ThreadLocalRandom:—1.7版本

int nextInt(int origin, int bound) 返回指定原点(含)和指定边界(排除)之间的伪随机 int值。

生成 [origin,bound)

UUID:生成的是一个唯一不重复的随机数

static UUID randomUUID() 静态工厂检索一个类型4(伪随机生成)的UUID。

四十、System

static long currentTimeMillis() 返回以毫秒为单位的当前时间。

static void gc() 运行垃圾回收器。 java里面的垃圾回收器是自动回收

这个方法只能主动的催促运行垃圾回收器,但是不是立即运行

static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。

1. Runtime

获取Runtime的对象

static Runtime getRuntime() 返回与当前 Java 应用程序相关的运行时对象。

方法

Process exec(String command) 在单独的进程中执行指定的字符串命令。 可以调用windows程序

void gc() 运行垃圾回收器。

四十一、和时间相关的类

1. java.util.Date[学习]

1.1 构造方法

Date() 分配一个 Date对象,并初始化它,以便它代表它被分配的时间,测量到最近的毫秒。

Date(long date) 分配一个 Date对象,并将其初始化为表示自称为“时代”的标准基准时间以后的指定毫秒数,即1970年1月1日00:00:00 GMT。

方法或者类已弃用【已过时】

这一类的方法或者类都是不建议再使用了,但是不是不能用。

win10 — win xp

2. 时间的格式化

2.1 为什么需要时间的格式化?

默认打印时间的格式为:Sat Nov 13 14:19:49 CST 2021 不符合国内的习惯

SimpleDateFormat:时间格式化的类

SimpleDateFormat(String pattern) 使用给定模式 SimpleDateFormat并使用默认的 FORMAT语言环境的默认日期格式符号。

pattern:用户指定的格式 例如国内习惯时间 2021-11-13 14:23:56

yyyy-MM-dd HH:mm:ss

String format(Date date) 将日期格式化成日期/时间字符串。

Date parse(String source) 从给定字符串的开始解析文本以生成日期。

四十二、异常

代码出现不正常的情况

1. 异常体系

Object

|–Throwable

|–Error –体系下面的问题,可能都是一些硬件等问题,可能不是通过代码能解决的

例如一段程序需要联网传输数据

|–Exception–体系下面的问题,都是一些参数,调用方式等问题造成

2.宏观说一下java里面的异常

1.捕获异常

2.抛异常

在我看来不管是哪一种解决方案,都没真正的去处理异常本身的问题

1.捕获异常

语法:

1
2
3
4
5
6
7
8
9
try{
//可能产生异常的代码
}catch(捕获的异常类型 e){//e是形式参数
//该异常捕获之后要做的操作
}catch(捕获的异常类型 e){//e是形式参数
//该异常捕获之后要做的操作
}finally{//视情况而定
//异常发生之后一定会执行到的语句块:①流资源关闭②释放锁
}

执行流程:

如果try 里面的代码 出现了错误,就立即执行catch里面代码

如果try 里面的代码没有错误,就不执行catch里面的代码

finally里面的代码 无论try里面代码有没有发生异常都要去执行 finally里面的代码

2. catch:里面的异常处理方案

1.记录日志——方便后期排错–log4j

2.打印异常信息(前期多是这种方案)e.printStackTrace();

3.获取错误信息–可以做额外处理

3. 总结

捕获异常有什么效果:对于可能发生异常代码做捕获的处理,在后期运行的如果发生异常不会因为异常而导致整个程序停止运行

4. 异常的处理方案2

抛异常:不处理异常

语法:

在方法的后面加关键字throws 抛出的异常类型

1
2
3
public void 方法名字() throws 异常类型1,异常类型2{

}
4.1 抛异常的执行特点

一旦发生异常后面的代码就停止执行

java里面的异常类是非常多的,其实大多数的异常类里面的都没有额外逻辑

java里面之所以定义很多异常类主要的目的就是为了进行错误的分类

例如:ArithmeticException:算术异常–一般是因为不符合数学规范造成错误

NullPointerException:空指针异常–一般是因为使用一个空对象去调用方法出现的错误

ArrayIndexOutOfBoundsException:索引越界–一般是因为数组的角标超出索引范围

ClassCastException:类型转换异常–一般是因为类型不一致之间的转换造成

4.2 为什么需要自定义异常

我们可以自己去扩展,异常的类型来符合功能业务的需要

四十三、创建启动线程方法一

创建并启动线程的方式一

继承Thread类

public class Thread extends Object implements Runnable

1.写一个类继承Thread

2.覆写run方法

3.创建类的实例【对象】,并且调用start()方法

常用方法:

void start() 导致此线程开始执行;

Java虚拟机调用此线程的run方法。

【这个方法会开启一个新的线程并且调用run()方法】

注意点:

启动线程是调用的start()方法

1.下面的代码有几个线程?

答:3个线程

main–主线程–开启两个新的线程

musicThread.start();

gameThread.start();

2.如果我调用的是 run() 和start()有什么区别?

答:调用run方法 仅仅只是在主线程,对象调用方法,不会开启新的线程

start(),开启一个新的线程,准备就绪去尝试分配CPU资源,由JVM去调用里面的run方法执行逻辑

1.每一个线程都应该做不同的事情

2.官方在定义这个run方法时候能不能去决定用户的业务逻辑–不能

3.覆写这个run方法主要的目的就是让用户自己去定义自己的逻辑

3. Thread里面常用的一写方法的汇总

1
static Thread currentThread()  //返回对当前正在执行的线程对象的引用。
1
String getName()  //返回此线程的名称
1
void setName(String name)  //将此线程的名称更改为等于参数 name 。
1
static void sleep(long millis)  //线程休眠

四十四、创建并启动线程方法二

实现Runnable接口【掌握】

1.自己去新建一个类,实现Runnable接口

2.实现接口里面的run 方法 自己去定义线程的业务逻辑

3.创建一个Runnable实现类的对象,作为一个Thread对象的参数

4.调用start方法启动线程

四十五、解决线程安全问题

1. 同步方法

1.把可能发生线程安全问题的代码抽取成一个方法

2.在方法上面添加一个synchronized

2. 同步代码块

1
2
3
synchronized (控制同步资源) {

}

控制同步资源—–>WindowThread.class —>Class实例(唯一性) 在Jvm里面只有一份

3. 解决线程安全问题

同步锁-Lock –接口

1.有一把锁

2.上锁

  1. 做里面逻辑

4.释放锁

Lock –接口—创建对象

–实现类 ReentrantLock

常用方法:

void lock() 获得锁。 【上锁】

void unlock() 释放锁。

4. 注意

锁为共享锁,必须要加static

在使用阻塞等待获取锁的方式中,必须在try代码块之外,并且在加锁方法与try代码块之间没有任何可能抛出异常的方法调用,,避免加锁成功后,在finally中无法解锁。

四十六、定时器

1. 创建一个定时任务

1.时间

2.任务

Timer【java.util】

线程调度任务以供将来在后台线程中执行的功能。 任务可以安排一次执行,或定期重复执行。

2. 构造方法

Timer() 创建一个新的计时器。

3. 常用方法

1
void cancel()  //终止此计时器,丢弃任何当前计划的任务。
1
void schedule(TimerTask task, Date time)  //在指定的时间安排指定的任务执行。
1
void schedule(TimerTask task, Date firstTime, long period)  //从指定 的时间开始 ,对指定的任务执行重复的 固定延迟执行 。
1
void schedule(TimerTask task, long delay)  //在指定的延迟之后安排指定的任务执行。
1
void schedule(TimerTask task, long delay, long period)  //在指定 的延迟之后开始 ,重新执行 固定延迟执行的指定任务。

time:未来执行的时间点

System.currentTimeMillis() 当前的时间

System.currentTimeMillis()+1000*10 在当前时间上面+10秒钟

new Date(System.currentTimeMillis()+1000*10) 创建一个延后10秒钟的时间Date对象

4. JDK官方能不能提前帮用户统一的定义好定时任务的逻辑 ?

这任务具体的逻辑需要用户自己去写,官方来讲 顶多只能定义好标准【接口,抽象类】

断定TimerTask 不是接口 就是抽象类

task:任务

四十七、数据装填的方式

1.变量—只能放指定类型的一个数据 booolean b= true;

2.数组—能够放指定类型 多个数据

2.1 数组也有类型的约束 int[] String[]

2.2 数组的长度一旦申明以后 长度就不能够改变了 new int[10];

四十八、ArrayList

能够存储任意类型,任意长度的容器

1. 底层原理

1.底层可以定义一个数组来存储数据 Object[]

2.添加数据方法【如果发现容量不够的时候,可以自动扩容】

3.提供一个获取数据方法【根据索引去获取】

4.返回存储了多少个数据的方法

5.删除数据的方法

2.ArrayList里面的常用方法

1.使用频率高的

1
boolean add(E e)  //将指定的元素添加到此列表的尾部。
1
E get(int index) // 返回此列表中指定位置上的元素。
1
E remove(int index)  // 移除此列表中指定位置上的元素。
1
int size()   //返回此列表中的元素数。

2.偶尔用一下

1
void add(int index, E element) //将指定的元素插入此列表中的指定位置。
1
void clear()    //移除此列表中的所有元素。
1
Object[] toArray()  //按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

四十九、集合的遍历

把集合里面的所有的数据取出来

1.普通for循环

Object get(int index); 获取指定索引位置的值

int size(); 返回集合的长度

2.增强for循环

3.迭代器

3.1 获取迭代器

1
Iterator iterator()   //返回一个在一组 T 类型的元素上进行迭代的迭代器

3.2 循环

Iterator

1
boolean hasNext()  //如果仍有元素可以迭代,则返回 true。
1
E next()   //返回迭代的下一个元素。
1
void remove()  //移除一个元素

一个list里面 现有数据[“AA”,”BB”,”CC”,”DD”,”EE”,”FF”,”GG”]

for(int i=0;i<list.size();i++){

list.remove(i)

}

答:还剩BB DD FF

原理为动态变化,当第一次删除时删除AA,还剩BB CC DD EE FF GG

当第二次删除时删下标为1的值也就是CC,还剩BB DD EE FF GG

当第三次删除下标为2的值也就是EE,还剩BB DD FF GG

当第四次删除下标为3的值也就是GG,还剩BB DD FF

i=3时结束循环

第一次环:i =0 [“BB”,”CC”,”DD”,”EE”,”FF”,”GG”] i=1 size=6

第二次循环:i =1 [“BB”,”DD”,”EE”,”FF”,”GG”] i=2 size=5

第三次循环:i =2 [“BB”,”DD”,”FF”,”GG”] i=3 size=4

第四次循环:i =3 [“BB”,”DD”,”FF”] i=4 size=3 判断为false 结束循环

请问以上代码 for循环几次 ,删除哪些数据,剩余哪些数据?

重点:移除数据以后 list的size是会动态变化

for(int i=0;i<list.size();i++){

list.remove(i)

}

五十、List(接口)

ArrayList LinkedList

都是集合容器

1.如何创建一个容器

2.如何添加数据

3.如何获取数据

4.遍历数据

5.移除数据

1. 构造方法

LinkedList() 构造一个空列表。

1.1 常用的方法【必须掌握】

1
boolean add(E e)   //将指定元素添加到此列表的结尾。
1
E get(int index)    //返回此列表中指定位置处的元素。
1
E remove(int index) //移除此列表中指定位置处的元素。
1
int size()   //返回此列表中的元素数。

1.2 了解的方法【有印象】

针对链表的结构 提供了很多操作头和尾的方法

1
void addFirst(E e)   // 将指定元素插入此列表的开头。
1
E getFirst()  //返回此列表的第一个元素。
1
E getLast()  // 返回此列表的最后一个元素。

2. 以后在工作中使用LinkedList还是ArrayList?

LinkedList:删除数据,添加数据速度较快

ArrayList:查询速度较快。

五十二、Set

(无序【添加顺序】不可重复的容器)

|–HashSet

|–TreeSet

|–HashSet

1.如何创建容器HashSet

构造方法

HashSet() 构造一个新的空 set

2.维护数据的方法

1
boolean add(E e)  //如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。
1
void clear()     //移除此 set 中的所有元素(可选操作)。
1
boolean remove(Object o)   // 如果 set 中存在指定的元素,则将其移除(可选操作)。
1
Iterator<E> iterator()   // 返回在此 set 中的元素上进行迭代的迭代器。
1
int size()  //返回 set 中的元素数(其容量)。

|–HashSet –不允许放入重复的数据,

3. HashSet判断重复的标准

1.先判断元素的hashCode 是否一致

2.在hashCode相等情况下。继续通过equals方法来判断两个数据是否相等

如果hashCode相等和equals的结果为true 就认为是同一个值

Hash–本身也是一套算法,如果说存储的数据特别多,有可能值不同,hashcode值是一致

HashSet 基于HashMap实现,底层也是键值对,hash值一致 数组+链表+红黑树去实现的(1.8)

判断方法

  1. 在存储数据的时候,调用的hashCode的方法
  2. 如果不同,就是两个不同的对象,就存储数据
  3. 如果相同,调用equals方法来把存储的数据和容器里面的数据比较
  4. 返回是false【数据不一致】 就存储数据
  5. 返回的是 true【存储的数据已经重复】 就不存储数据

结论

如果一个类的对象要放到HashSet里面,覆写hashCode 和equals 方法

|–TreeSet

里面放的数据类型要一直,内部需要排序

1. 构造方法

TreeSet() 构造一个新的空 set

2. 维护数据的方法

1
boolean add(E e)  //如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。
1
void clear()   // 移除此 set 中的所有元素(可选操作)。
1
boolean remove(Object o)   // 如果 set 中存在指定的元素,则将其移除(可选操作)。
1
Iterator<E> iterator()   // 返回在此 set 中的元素上进行迭代的迭代器。
1
int size()  //返回 set 中的元素数(其容量)。

3. 自然排序

放到TreeSet里面的数据类型必须实现Comparable接口,并覆写里面的方法 public int compareTo(T o);

Comparable

|–int compareTo(T o)

0: 代表是重复的元素

正整数: 升序

负整数:降序

4. 如果身份证要排序,怎么排?

定制排序:

一个人 : 名字 年龄 手机号 地区

不同的人 有不同的理解

1.根据年龄排序 年龄小的排前面 年龄大 后面

2.名字,姓氏的首字符排序

3.地区,地区的首字符

五十三、Map

Map是一个全新的结构,和Collection没有半毛钱关系

将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

map存储数据的时候 键值对的形式

key不允许重复

一个key只能定义一个值

1. Map–接口

|–HashMap

1.1 构造方法

HashMap() 构造一个具有默认初始容量 (16)

1.2 常用方法

1
Object put(Object key, Object value)  //将指定的值与此映射中的指定键关联(可选操作)。 将添加和修改合为一体
1
int size()  //返回此映射中的键-值映射关系数。
1
void clear()  //从此映射中移除所有映射关系
1
Object get(Object key) //根据key 获取值
1
V remove(Object key)  //如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

1.3 遍历方式

遍历的方式一

把map里面所有的key取出来 返回一个Set集合

1
Set<K> keySet()   //返回此映射中包含的键的 Set 视图。

遍历的方式二

把map里面所有的Value取出来

1
Collection<V> values()   //返回此映射中包含的值Collection 视图

遍历的方式三

1
Set<Map.Entry<K,V>> entrySet()   //返回此映射中包含的映射关系的 Set 视图。

五十四、TreeSet

构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。

TreeSet(Comparator comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。

TreeSet:存储数据

自然排序

类必须实现Comparable接口

定制排序

1.针对要存储的数据单独写一个比较类【排序的规则】,实现接口Comparator

2.覆写方法compare,编写比较的逻辑

3.在创建容器对象的时候传入比较类的对象

五十五、泛型

作用:泛型就是一种约束,例如集合里面的数据,只能放指定类型

在定义的时候不去指定具体的类型,在使用的时候由使用者自己去指定类型

1. 注意事项

1.泛型如果不加,类型就是Object

2.泛型不支持基本数据类型

Point 就是一个泛型类

T由用户在使用的时候去指定T的类型

2. 定义泛型的规范

T(Type):类型

E(Element):元素

K(Key):键

V(Value):值

如果用double:领导找到你 说 double不精确

–把类型改String

String:操作起来可能有些不方便 要转换

–要不还是用double

3. 多个团队合作

A团队:String要好用一点,准确

B团队:double要好用一些,操作起来方便 不用转换

五十六、Properties

1
public class Properties extends Hashtable
1
void load(InputStream inStream)  //从输入流中读取属性列表(键和元素对)。
1
void list(PrintStream out)  //将属性列表输出到指定的输出流。
1
String getProperty(String key)  //用指定的键在此属性列表中搜索属性。
1
Object setProperty(String key, String value)   //调用 Hashtable 的方法 put。

五十七、collection与map的简易关系图

Collection

–List:以特定顺序存储

–ArrayList、LinkList、Vector

–Set:不能包含重复的元素

–HashSet、TreeSet

Map

–HashMap、HashTable、TreeMap

五十八、ArrayList LinkedList HashSet TreeSet HashMap关系图

添加的方法 获取值方法 移除的方法 遍历的方式
ArrayList add() get() remove() for、foreach、 Iterator
LinkedList add() get() remove() for、foreach、 Iterator
HashSet add() contains() remove() foreach、 Iterator
TreeSet add() foreach、 Iterator
HashMap put() get() remove() foreach、 Iterator

五十九、File

1.文件

2.文件夹

在Java里面一个File对象就是表示一个文件夹 或者 文件

1. 构造方法

File(String pathname) 通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent, String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。

File(File parent, String child) 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

File这个类,既可以表示文件,又可以表示文件夹

2. File里面的一些常用方法

1
boolean createNewFile()  //创建文件   注意:不能创建文件夹
1
2
3
boolean delete()   //删除此抽象路径名表示的文件或目录。

//注意:只能去删除文件或者空文件夹
1
boolean exists()  //测试此抽象路径名表示的文件或目录是否存在。
1
String getName()  //返回由此抽象路径名表示的文件或目录的名称。
1
String getParent()  //返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
1
File getParentFile()    //返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
1
boolean isDirectory()   //测试此抽象路径名表示的文件是否是一个目录。
1
boolean isFile()     //测试此抽象路径名表示的文件是否是一个标准文件。
1
boolean mkdir()  // 创建此抽象路径名指定的目录。
1
2
boolean mkdirs()  //创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。

注意:没有权限是不能操作的

3. File里面关于列表的一些方法

1
static File[] listRoots() //列出可用的文件系统根。
1
String[] list()  //返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
1
File[] listFiles()  //返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

4. 什么是递归调用

简单的理解在一个方法的内部自己调用自己

方法的递归调用的注意事项:

递归必须要有出口,如果没有出口最终只有一个结果 栈内存溢出 StackOverflowError

六十、斐波拉契数列

1. 已知条件

f(0)=0 f(1)=1

已知有个公式 f(n)=f(n-1)+f(n-2) 前提条件 n>=2

f(2)=f(1)+f(0) =1

f(3)=f(2)+f(1) =2

f(4)=f(3)+f(2) =3

f(5)=f(4)+f(3) =5

f(6)=f(5)+f(4) =8

使用程序算 f(5) 等于多少?

2. 对于递归调用

1.知道是怎么一回事就可以了

2.递归的次数越多,效率越低

3.理解这种思想就够了,后面其实很少用到

4.哪些地方要使用递归,有层级关系,菜单栏

六十一、字节流

1. 字节输入流

1.每次读取的单位是一个字节

2.写程序去文件里面读取数据【把文件里面的数据取出来】

InputStream:字节输入流的所有类的父类

抽象类:不能直接创建对象【不能new】,如果要创建对象,找InputStream的子类

FileInputStream:用于读取诸如图像数据之类的原始字节流

1.1 构造方法

FileInputStream(File file) 就是去读取一个指定的文件

FileInputStream(String name) 读取一个指定文件【传入文件的路径】

1.2 常识

1.一个字母占一个字节

2.一个中文占两个字节【GBK】

1.3 读取数据的方法

大多数读取的数据方法都叫-read

int read() 从此输入流中读取一个数据字节。 返回字母的ASCII ,如果已到达文件末尾,则返回 -1。

2. 字节输出流

1.输出的单位 字节

2.输出流,把数据写到文件里面去

OutputStream:抽象类

2.1 FileOutputStream

1
FileOutputStream(File file)   //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
1
FileOutputStream(File file, boolean append)  //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
1
FileOutputStream(String name)  //创建一个向具有指定名称的文件中写入数据的输出文件流。
1
FileOutputStream(String name, boolean append)   //创建一个向具有指定 name 的文件中写入数据的输出文件流。

append:如果为true 就是追加内容
append:如果是false 或者不写 就是覆盖内容

2.2 输出内容的方法

1
2
3
void write(int b)  //将指定字节写入此文件输出流。


1
void write(byte[] b)   //将 b.length 个字节从指定 byte 数组写入此文件输出流中。
1
void write(byte[] b, int off, int len)  //将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

off:从b这个数组里面第几个位置开始写出数据

len:写几个数据出去

2.3 写出中文

1
void write(byte[] b)   //将 b.length 个字节从指定 byte 数组写入此文件输出流中。
1
void write(byte[] b, int off, int len)  //将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

off:从b这个数组里面第几个位置开始写出数据

len:写几个数据出去

中文

gbk:占2个字节

UTF-8:占3个字节

3. 字节流特点

1.不适合读取中文,如果说一段数据 边读取边查看
2.多用于去读取视频,音频,图片等二进制文件【不适合去读取一些文字类的文件 txt doc】

六十二、字符流

1. 字符输入流

Reader:用于读取字符流的抽象类

FileReader:

1.1 构造方法

1
FileReader(String fileName)   //在给定从中读取数据的文件名的情况下创建一个新 FileReader。
1
FileReader(File file)  //在给定从中读取数据的 File 的情况下创建一个新 FileReader。

1.2 读取数据

1
int read()   //读取单个字符。  如果达到文件末尾 返回-1
1
int read(char[] cbuf)  //将字符读入数组。

BufferReader 这个类里面有一个方法叫做readLine() 可以一次性读取一行数据

要求:大家立即查看api文档,学习这个类 读取一个java文件在控制台打印内容。

2. 字符输出流

Writer:-抽象类

2.1 构造方法

1
FileWriter(File file)   //根据给定的 File 对象构造一个 FileWriter 对象。
1
FileWriter(File file, boolean append)  //根据给定的 File 对象构造一个 FileWriter 对象。
1
FileWriter(String fileName)   //根据给定的文件名构造一个 FileWriter 对象。
1
FileWriter(String fileName, boolean append)   //根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

3. 字符流特点

一般适合去操作文本文件

六十三、字节输入流 —-字符输入流

InputStreamReader

InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。

六十四、把字节输出流—字符输出流

OutputStreamWriter

OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。

六十五、自动关流

java 1.7以后针对这种关闭流资源比较臃肿的情况提供了一种新的结构

需要自动关闭的流资源-必须实现AutoCloseable接口

1
2
3
4
5
6
7
8
9
try(需要自动关闭的流资源){

可能发生异常的代码块

}catch(){

捕获异常之后要做的处理

}

六十六、 接口的默认方法

1.1. 传统的方法(之前的)

在Java8之前Java中接口里面的方法默认都是public abstract 修饰的抽象方法并且没有方法体;

1.2. static方法

1、使用static修饰接口中的方法并且必须有主体;

2、接口的static方法只能够被接口本身调用;接口名.方法名(…);

3、接口的static方法不能够被子接口继承;

4、接口的static方法不能够被实现类覆写及直接调用;

1.3. default方法

在接口中可定义一个使用default修饰有方法体的方法,接口中可以对这个方法提供默认的一种实现。

1、使用default修饰接口中的方法并且必须有主体;

2、接口的default方法不能够被接口本身调用,需要接口的实例(实现类对象)来调用;

3、接口的default方法可以被子接口继承、覆写或者直接调用;

4、接口的default方法可以被实现类覆写及直接调用;

在接口中,经过static和default修饰的方法必须有方法体;

static修饰的方法调用方式为类.方法名

default修饰的方法必须是实现类的对象调用

static修饰的方法不能被子接口继承,default修饰的方法可以被子接口继承

并复写方法,就可以创建子接口实现类对象进行调用

六十七、接口里面可以有哪些内容

抽象方法

成员变量

1. jdk8以后

静态方法 — 静态方法如何去调用 类名.方法名()

默认方法 — 默认方法如何使用 实现类对象.方法名()

在Java8以后新增了一个注解

1.2函数式接口

就是一种要求,把只有一个抽象方法的接口叫做函数式接口【静态方法和默认方法个数无关】

回顾一下:我们以前学过的接口里面 哪些有以上特征【函数式接口】

Runnable

Comparator:定制排序

@FunctionalInterface:可以去验证一接口是否是函数式接口

1
2
3
4
基本语法:
<函数式接口> <变量名> = (参数1,参数2...) -> {
//方法体
}

(参数1,参数2…)表示参数列表;->表示连接符;{}内部是方法体
1、=右边的类型会根据左边的函数式接口类型自动推断;
2、如果形参列表为空,只需保留();
3、如果形参只有1个,()可以省略,只需要参数的名称即可;
4、如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句;
5、形参列表的数据类型会自动推断;
6、lambda不会生成一个单独的内部类文件;
7、lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错

六十八、Lambda表达式

Lambda:主要是针对匿名内部类简写优化【借鉴了前端的语法】

Lambda表达式只能对函数式接口进行书写

lambda表达式不会产生字节码文件

java8以后,更推荐链式编程

Stream:就是针对数据进行一些连续的操作

六十九、数据库的数据

1.筛选

2.排序

3.分组

4.分页

七十、 Stream流

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  1. <strong元素队列< strong=””>元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。</strong元素队列<>

  2. 数据源 流的来源。 可以是集合,数组,I/O channel(nio new IO非阻塞式IO), 产生器generator 等。

  3. 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  1. Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  2. . 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

1.1. 生成流

在 Java 8 中, 集合接口有两个方法来生成流:

stream() − 为集合创建串行流。

parallelStream() − 为集合创建并行流。