day7 day07 线程间通信 线程池 Lambda表达式
线程间通信
等待唤醒机制介绍
wait(): 让当前线程处于无限等待状态, 同时释放锁
notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
调用 wait() 和 notify() 需要注意的细节:
1. wait() 与 notify() 必须要由"同一个锁对象"调用
2. wait() 与 notify() 是属于Object类的方法
3. wait() 与 notify() 必须要在"同步代码块"或者是"同步方法"中使用
线程池
创建线程池对象
ExecutorService es = Executors.newFixedThreadPool(2);
提交任务
es.submit(new RunnableImpl());
销毁线程池
es.shutdown();
函数式编程思想: Lambda表达式
Lambda表达式的3个部分:
??1. 一些参数 ()
接口中抽象方法的参数列表. 没参数就空着; 有参数就写, 多个参数用逗号分隔
??2. 一个箭头 ->
将参数传递给方法体
??3. 一段代码 {}
重写接口抽象方法的方法体
函数式接口:
函数式接口: "有且仅有一个抽象方法的接口"
但函数式接口对于 哪些方法算作抽象方法 有特殊规定:
1. 有方法体的方法"不算作"抽象方法, 如默认方法, 静态方法, 私有方法
2. 如果一个抽象方法 与 java.lang.Object类中的方法 定义相同的, 也"不算作"抽象方法
因为任何实现本接口的实现类, 都会直接或间接继承java.lang.Object类的public的方法, 所以
在创建实现类时其实不用重写该抽象方法, 也就不算作抽象方法
Lambda省略格式和使用前提
可以省略的部分:
1. (参数列表): 参数"类型"可以省略 (a, b) -> {}
2. (参数列表): 如果参数只有1个, 则"类型"和"小括号"都可以省略 ?a -> sout(a)
3. {一些代码}: 如果只有一条代码, 则"大括号", "return", "分号"都可以"一起省略"
day08 File类 递归笔记
File类
我们可以对File进行的操作:
创建文件/目录
删除文件/目录
获取文件/目录
判断文件/目录是否存在
对目录进行遍历
获取文件的大小
File(String) 根据 路径字符串 封装一个File对象
String?getAbsolutePath(): 返回此File的绝对路径名字符串
String?getPath(): 获取File对象的封装路径 (创建对象时传入的路径)
String?getName(): 获取File对象的文件名或目录名 ?d:\a\b\c\aaa.txt
long?length(): 获取File表示的"文件"大小的字节byte数 (不能获取目录的大小)
exists(): 判断File对象代表的文件或目录是否实际存在
isDirectory(): 判断File表示的是否为目录
isFile(): 判断File表示的是否为文件
createNewFile(): 当文件不存在时, 创建一个新的空文件
delete(): 删除
mkdir(): 创建File表示的目录
list(): 获取当前File目录下的所有子文件或目录的名字数组
listFiles(): 获取当前File目录中的所有子文件或目录的File对象数组
递归的概念, 分类, 注意事项
递归时的注意事项:
1. 递归要有限定条件(出口), 保证递归能够停止(就是在某种情况下方法不再调用自己), 否则会栈内存溢出
2. 递归次数不能太多, 否则会栈内存溢出
3. 构造方法不能递归
FileFilter文件过滤器的原理和使用
for (File file : demo.listFiles()) {
if (file.isDirectory()){
show(file);
}else {
System.out.println(file);
}
day09 字节流 字符流 Properties
输入流 输出流
字节流 字节输入流 InputStream 字节输出流 OutputStream
字符流 字符输入流 Reader 字符输出流 Writer
close() :释放资源
flush() :刷新缓冲区(对于字节流来说没有作用)
write()写一个字节
read(): 一次读一个字节
JDK7和JDK9中IO异常处理的不同方式
try-with-resource
Properties集合
Properties() 创建一个Properties集合
getProperty(String?key): 通过键获取值. 键不存在返回null
setProperty(String?key,?String?value): 保存/替换键值对
stringPropertyNames(): 返回键的集合
store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能中文)
day10 缓冲流 转换流 序列化流 打印流
缓冲流: BufferedInputStream / BufferedOutputStream, BufferedReader / BufferedWriter
在基本流上增加缓冲区 char[] byte[], 提高读写效率
转换流: InputStreamReader / OutputStreamWriter
字节转字符: FileReader 读 char <- byte 硬盘
字符转字节: FileWriter 写 char -> byte 硬盘
序列化流: ObjectInputStream / ObjectOutputStream
序列化: 内存中的对象 写-> 硬盘上的文件中
反序列化: 内存中的对象 <-读 硬盘上的文件中
打印流: PrintStream
可以自动换行, 原样输出 ?System.out.println();
只有输出流, 没有输入流
PrintStream不会抛出IOException
有特殊方法 print(), println(), 可以输出任意类型的值, 原样输出
transient瞬态关键字: 避免属性序列化
static 修饰的成员变量属于类不属于对象, 所以不能序列化
transient 修饰的成员变量, 不能被序列化
InvalidClassException异常: 原因和解决方案
序列化操作时, 会根据类生成一个默认的 serialVersionUID 属性, 写入到文件中.
该版本号是根据类中成员计算出来的一个数值. 当类的成员发生改变时, 序列版本号也会发生变化
当代码中的类和读取的对象序列版本号不一致时, 就会抛出InvalidClassException
为了避免这种问题, 我们可以手动写死这个序列号, 这样无论成员如何变化, 序列版本号都是一样的
|