此部分的代码演示全部在day12文件夹中
第一章 Lambda表达式
1.1 函数式编程思想概述
- 面向对象的思想:做一件事,找一个能解决这个事情的对象,调用对象的方法,完成事情
- 函数式编程思想:只要能获取到结果,怎么做的都不重要,重视的是结果,不重视过程
- 简单的说,面向对象强调必须通过对象的形式来做事情;函数式思想强调做什么,而不是以什么形式做
1.2 Lambda表达式格式
由三部分组成:一些参数、一个箭头、一段代码
格式:(参数列表) -> { 一些重写方法的代码 }
1.2.1 练习:无参无返回值
// Cook接口
public interface Cook {
public abstract void makeFood();
}
// 主函数
public static void main(String[] args) {
invokeCook(()-> {
System.out.println("做饭")
});
}
public static void invokeCook(Cook cook) {
cook.makeFood();
}
1.2.2 练习:有参有返回值
public static void main(String[] args) {
Person[] arr = {
new Person("孙磊1", 18),
new Person("孙磊2", 16),
new Person("孙磊3", 19)
};
// 排序
Arrays.sort(arr, (Person o1, Person o2) -> {
return o1.getAge() - o2.getAge();
});
// 遍历
for (Person person : arr) {
System.out.println(person);
}
}
1.2.3 lambda省略格式
- (参数列表):括号中参数列表的数据类型,可以省略不写
- 如果括号中的参数只有一个,那么类型和()都可以省略
- {一些代码}:如果{}中的代码只有一行,可以省略{}
- 如果{}中的代码只有一行return语句,那么省略return和{}
1.2.4 lambda的使用前提
- 使用lambda必须具有接口,且要求接口中有且仅有一个抽象方法。
- 使用lambda必须具有上下文推断。
有且仅有一个抽象方法的接口,称为"函数式接口"
第二章 File类
2.1 概述
java.io.File
类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作
路径注意事项:路径是不区分大小写的;路径中的两个反斜杠代表一个普通的反斜杠
2.2 静态成员变量
String pathSeparator = File.pathSeparator; // windows: ; linux: :
String separator = File.separator; // windows: \ linux: /
以后开发中不要把路径写‘死’了,使用静态成员变量来拼接路径
2.3 构造方法
- File(String pathname):通过将给定路径名字的符串转换为抽象路径名来创建一个新File实例。
- 路径可以存在,也可以不存在
- File(String parent, String child):根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
- File(File parent, String child):根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
2.4 常用方法
2.4.1 获取功能的方法
public String getAbsolutePath()
:返回此File的绝对路径名字符串public String getPath()
:将此File转换为路径名字符串- toString方法调用的就是getPath方法
public String getName()
:返回由此File表示的文件或目录的名称**(结尾部分)**public long length()
:返回由此File表示的文件的长度(以字节为单位,文件夹为0)
2.4.2 判断功能的方法
public boolean exists()
:此File表示的文件或目录是否实际存在public boolean isDirectory()
:此File表示的是否为目录- 使用前提:路径必须是存在的,否则返回false
public boolean isFile()
:此File表示的是否为文件- 使用前提:路径必须是存在的,否则返回false
2.4.3 创建删除功能
public boolean createNewFile()
:当且仅当具有该名称的文件尚不存在时,创建一个新的空文件- 文件存在,不会创建并且返回false
- 创建文件的路径必须存在,否则会抛出异常
public boolean delete()
:删除由此File表示的文件或目录- 不会到回收站
public boolean mkdir()
:创建由此File表示的目录- 只能创建单级文件夹
public boolean mkdirs()
:创建有此File表示的目录,包括任何必需但不存在的父目录- 单级文件夹或者多级文件夹都可以创建
2.5 目录的遍历
-
public String[] list()
:返回一个String数组,表示File目录中的所有子文件或目录 -
public File[] listFiles()
:返回一个File数组,表示File目录中的所有子文件或目录// 递归打印多级目录 public static void getAllFile(File dir) { System.out.println(dir); File[] files = dir.listFiles(); for (File f : files) { if (f.isDirectory()) { getAllFile(f); } else { System.out.println(f); } } }
第三章 IO流
1.1 IO概述
- I:input 输入 (读取) 把硬盘中的数据,读取到内存中使用
- O:output 输出 (写入) 把内存中的数据,写入到硬盘中保存
- 流:数据(字符,字节)1个字符=2个字节
1.2 字节流
1.2.1 一切皆为字节
- 一切文件数据,都是以二进制数字的形式保存
- 无论使用什么样的流对象,底层传输的始终为二进制数据
1.2.2 字节输出流
-
java.io.OutputStream
:此抽象类是表示字节输出流的所有类的超类 -
成员方法:
public void close()
:关闭此输出流,并释放资源public void flush()
:刷新此输出流,并强制任何缓冲的输出字节被写出public void write(byte[] b)
:将指定的字节数组写入此输出流中public void write(byte[] b,int off,int len)
:从指定的字节数0组写入len字节,从偏移量off开始输出到此输出流public void write(int b)
:将指定的字节写入此输出流中
写换行:\r\n (windows) /n(linux) /r(mac)
1.2.3 FileOutputStream
-
java.io.FileOutputStream
:继承了OutputStream类,它是文件字节输出流,用于将数据写出到文件中 -
构造方法:
FileOutputStream(String name)
:创建一个向具有指定名称的文件中写入数据的输出文件流。FileOutputStream(String name, boolean append)
: 创建一个向具有指定名称的文件中写入数据的输出文件流。(可进行文件的追加写入)FileOutputStream(File file)
:创建一个向具有指定File对象表示的文件中写入数据的输出文件流。FileOutputStream(File file, boolean append)
: 创建一个向具有指定File对象表示的文件中写入数据的输出文件流。
参数:name/file:写入数据的目的地 append:追加写开关
作用:1.创建一个对象 2.创建一个空文件 3.对象指向空文件
-
写入数据的原理(内存–>硬盘):
- java程序–>JVM(java虚拟机)–>OS(操作系统)–>OS调用写数据的方法–>把数据写入到文件中
-
字节输出流的使用步骤:
- 创建一个FileOutStream对象,构造方法中传递写入数据的目的地
- 调用对象的write方法,把数据写入文件中
- 释放资源
1.2.4 字节输入流
java.io.InputputStream
:此抽象类是表示字节输出流的所有类的超类- 成员方法:
int read()
:从输入流中读取数据的下一个字节(返回读取的该字节)int read(byte[] b)
:从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中(返回读取的有效字节个数)void close()
:关闭输入流并释放与该流关联的所有系统资源
1.2.5 FileInputStream
-
java.io.FileInputStream
:继承了InputStream类,它是文件字节输入流,将数据读取到内存中使用 -
构造方法:
- FileInputStream(String name)
- FileInputStream(File file)
参数:读取文件的数据源
作用:1.创建一个对象 2.对象指向要读取的文件
-
读取数据的原理(硬盘–>内存):
- java程序–>JVM–>OS–>OS读取数据的方法–>读取文件
-
字节输入流的使用步骤:
- 创建一个FileInputStream对象,构造方法中绑定要读取的数据源
- 调用对象中的read方法,读取文件
- 释放资源
-
String的构造方法:
- String(byte[] bytes):将字节数组转换为字符串
- String(byte[] bytes, int offset, int length):把字节数组的一部分转换为字符串,offset为起始索引,length为转换的字节个数
补充:
- char(byte b):将字节转换成字符
- “hello”.getBytes():将字符串转换成字节数组
- GBK:1个中文占用两个字节 UTF-8:1个中文占用三个字节
1.3 字符流
1.3.1 字符输入流
-
java.io.Reader
:此抽象类是表示字符输入流的所有类的超类 -
成员方法:
int read()
:读取单个字符并返回(每个字符单独用一个数值表示)int read(char[] cbuf)
:一次读取多个字符,将字符读入数组中void close()
:关闭该流并释放资源
将读取到的字符len,使用char(len)
1.3.2 FileReader
java.io.FileReader
:extends InputStreamReader extends Reader,它是文件字符输入流,把硬盘中的数据以字符的方式读取到内存中- 构造方法:
- FileReader(String fileName)
- FileReader(File file)
- String的构造方法:
- String(char[] value):将字符数组转换为字符串
- String(char[] value, int offset, int count):把字符数组的一部分转换为字符串,offset为起始索引,count为转换的字符个数
1.3.3 字符输出流
java.io.Writer
:此抽象类是表示字符输出流的所有类的超类- 成员方法:
void write(int c)
:写入单个字符void write(char[] cbuf)
:写入字符数组void write(char[] cbuf, int off, int len)
:写入字符数组的某一部分void write(String str)
:写入字符串void write(String str, int off, int len)
:写入字符串的某一部分void flush()
:刷新该流的缓冲void close()
:关闭此流,但要先刷新它
1.3.4 FileWriter
java.io.FileWriter
:extends OutputStreamReader extends Reader,它是文件字符输出流,把内存中的字符数据写入到文件中- 构造方法:
FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)
- 字符输出的使用步骤(重点)
- 创建一个FileWriter对象,构造方法中绑定要写入数据的目的地
- 调用对象的write方法,把数据写入到内存缓冲区中(字符转换为字节的过程)
- 使用对象的flush方法,把内存缓冲区中的数据,刷新到文件中
- 释放资源(会先把内存缓冲区中的数据刷新到文件中)
1.4 补充(异常处理)
// try代码执行完毕之后,流对象会自动释放掉
// JDK7的新特性
try (定义流对象1;定义流对象2...){
// 可能产生异常的代码
} catch (异常类变量 变量名) {
// 异常的处理逻辑
}
// JDK9的新特性
A a = new A();
B b = new B();
try(a,b){
// 可能产生异常的代码
} catch (异常类变量 变量名) {
// 异常的处理逻辑
}
第四章 缓冲流
它都是在基本的流对象基础之上创建而来的,相当于是对基本流对象的一种增强
4.1 概述
- 缓冲流也叫高效流,是对4个基本的
FileXxx
流的增强,按照数据类型分为:- 字节缓冲流:
BufferedInputStream
、BufferedOutputStream
- 字符缓冲流:
BufferedReader
、BufferedWriter
- 字节缓冲流:
- 基本原理:在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数
4.2 字节缓冲流
- 构造方法:
public BufferedInputStream(InputStream in)
:创建一个新的缓冲输入流public BufferedInputStream(InputStream in,int size)
:创建一个新的缓冲输入流,并且指定缓冲区数组大小public BufferedOutputStream(OutputStream out)
:创建一个新的缓冲输出流public BufferedOutputStream(OutputStream out,int size)
:创建一个新的缓冲输出流,并且指定缓冲区数组大小
4.3 字符缓冲流
-
构造方法:
public BufferedWriter(Writer out)
:创建一个新的缓冲输出流public BufferedWriter(Writer out,int size)
:创建一个新的缓冲输出流,并且指定缓冲区数组大小public BufferedReader(Reader in)
:创建一个新的缓冲输入流public BufferedWriter(Reader in,int size)
:创建一个新的缓冲输入流,并且指定缓冲区数组大小
-
特有的成员方法:
- BufferedWriter
void newLine()
:写入一个行分隔符
- BufferedReader
String readLine()
:读取一个文本行
- BufferedWriter
第五章 转换流
5.1 OutputStreamWriter
-
概述:继承自Writer
-
作用:是字符流通向字节流的桥梁,可使用指定的charset将写入流中的字符编码成字节
-
构造方法:
OutputStreamWriter(OutputStream out)
:创建使用默认字符编码的字符输出流OutputStreamWriter(OutputStream out,String charsetName)
:创建使用指定字符集的字符输出流
参数: out:字节输出流 charsetName:编码表名称(不区分大小写),例utf-8/UTF-8、gbk/GBK,
不指定编码,默认utf-8
5.2 InputStreamReader
-
概述:继承自Reader
-
作用:是字节流通向字符流的桥梁,可使用指定的charset将读出流中的字节解码成字符
-
构造方法:
InputStreamReader(InputStream in)
:创建使用默认字符编码的字符输入流InputStreamReader(InputStream in,String charsetName)
:创建使用指定字符集的字符输入流
参数: in:字节输入流 charsetName:编码表名称(不区分大小写),例utf-8/UTF-8、gbk/GBK,
不指定编码,默认utf-8
第六章 序列化
6.1 ObjectOutputStream
- 概述:继承自OutputStream,叫做对象的序列化流
- 作用:把对象以流的方式,写入到文件中保存,叫写对象,也叫对象的序列化
- 构造方法:
ObjectOutputStream(OutputStream out)
- 特有成员方法
void writeObject(Object obj)
注意:要进行序列化和反序列化的类,必须实现Serializable接口(标记型接口),就会给类添加一个标记
当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记
有:就可以序列化和反序列
没有:就会抛出NotSerializableException异常
6.2 ObjectInputStream
- 概述:继承自InputStream,叫做对象的反序列化流
- 作用:把文件中保存的对象,以流的方式读取出来,叫读对象,也叫对象的反序列化
- 构造方法:
ObjectInputStream(InputStream in)
- 特有成员方法
Object readObject()
6.3 补充
-
transient关键字:瞬态关键字
- 被transient修饰的成员变量,不能被序列化
-
InvalidClassException异常:当序列化后,修改了class文件,反序列化时,会由于序列版本号不一致,发生此异常
-
解决方法:在定义的类中提供一个版本号
例如:
private static final long serialVersionUID = 10l;
-