回顾:
Map: - key-value键值对
HashMap
LinkedHashMap
TreeMap
Hashtable
ConcurrentHashMap
Node节点:
key value next hash
存储过程 put(key, value)
先定hash位置,确定key的位置,跟位置上的链表,每一个元素进行equals对比(key)
确定key重复,用新的value替换原来的value
确定key不重复,添加到链表末尾
Map常用API:
oldValue put(key, value)
value remove(key)
value get(key)
Map三种迭代方式:- 提供了Collection的三种视图
entrySet - key-value
keySet - key
values - value
Collection
ArrayList
Map
HashMap
Properties
LinkedList - 链表,灵活性
Collections - 工具类
sort
java.io
File -> 内存对象,表示文件/目录,和本地有没有这个文件/目录没关系
listFiles()
listFiles(FileFilter-accept)
getName()
....
isFile()
isDirectory()
---------------------------------------------------------
IO -> 输入/输出 读/写
对文件进行[随机]读写的类。不算IO,IO都是单向的
RandomAccessFile - 可读可写 - 使用场景:文件复制/文件加密
实例化 -> new
new (File/fileName, "rw")
API - 字节为单位
写
write * 3
write(b) -> 写入指定int值的低八位,单字节
write(bs) -> 写入指定的byte数组的全部字节
write(bs, offset, len) -> 截取一部分字节写入
write 8种基本数据类型
注意:写入到文件中的是字节,看到文件内容的是字符
字节 -> 字符 需要编码
读
read * 3 -> 返回-1表示读到文件末尾
int read() —> 读1个字节,并存入到int类型的低八位
返回读取出来的字节数
int read(bs) -> 读bs.length个字节,并且存入到bs中
int read(bs, off, len) -> 读len个字节,并且在bs中off位置开始存入
返回读取出来的有效字节个数
read 8种基本数据类型
随机:操作指针位置 pointer 读写操作,指针都会移动
1.获得当前指针位置
2.跳过对应字节数 -> 顺序
3.跳转到指定指针位置
从而实现 读写同时操作
Input: 输入/读
Output:输出/写
字节为单位:InputStream / OutputStream 流
字符为单位:Reader / Writer
回顾:
RandomAccessFile
new RandomAccessFile(file, "rw");
常用:
int read() -> 读单字节
int read(byte[]) -> 返回有效长度,读的内容放入byte数组
int read(byte[], off, len) ->
返回有效长度,读的内容放入byte数组off位置开始
void write(int) -> 写单字节
write(byte[]) -> 将byte数组写入文件
write(byte[], off, len) -> 将byte数组中从off位置开始写入文件,写len个
long getFilePointer()
seek(int)
skipBytes(int)
字节流:
InputStream / OutputStream
FileInputStream(file)
FileOutputStream(file, boolean)
缓冲流:
缓冲区:添加缓冲区的目的就是为了提高效率
访问磁盘空间,和访问缓存(内存),访问内存效率更高
访问磁盘空间:
文件读写
访问数据库
B/S:浏览器/服务器 C/S:客户端/服务器
字节缓冲流: - 字节为单位
BufferedInputStream
BufferedOutputStream
缓冲流是通过节点流包装出来的
字节流:字节为单位,不是用来读写可视内容
通常用来复制文件
又因为缓冲流效率高,所以复制文件用缓冲流
底层流就是用来生成其它高级流的
字符流:单位是字符 - 有字符集 默认字符集/指定字符集
Reader / Writer
InputStreamReader(InputStream, charset)
int read() - 读单个字符
int read(char[]) - 返回读取的有效个数,读出来的字符存入字符数组中
int read(char[], off, len) -
返回读取的有效个数,读出来的字符存入数组从off位置开始
OutputStreamWriter(OutputStream, charset)
write(int) - 写单个字符
write(char[]) - 写字符数组
write(char[], off, len) - 写字符数组一部分
flush()/close()
缓冲流:
BufferedReader(Reader(InputStream(file)))
readLine();
PrintWriter(Writer(OutputStream(file)))
PrintWriter(OutputStream(file))
PrintWriter(file)
print()
println()
课堂练习:
读取文件,将所有名字存储到List集合中
Collections -> 将List集合中所有元素打乱顺序打印出来
ObjectInputStream/ObjectOutputStream -- 操作对象,字节为单位
写:现将对象转换成字节(序列化),写入文件
读:读字节,将字节转换成对象(反序列化)
操作对象
使用场景:
深克隆:复制 对象 + 引用
使用场景:跨主机
浅克隆:object.clone() 复制引用
Serializable: 可序列化的 - 空接口
序列化:将对象转换成字节,要求对象必须是可序列化的
目的:仅用于标识可序列化的语义
serialVersionUID -> 类的版本号,默认情况下,通常修改内容会修改版本号
总结:
字节流:InputStream/OutputStream
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
字符流:Reader / Writer
InputStreamReader
OutputStreamWriter
BufferedReader
PrintWriter
文件复制:
BufferedInputStream
BufferedOutputStream
内容读写:
BufferedReader
PrintWriter
底层流:
包装高级流
Properties - key-value键值对
<String, String>
配置文件,避免硬编码,动态加载信息
.properties
.xml
连服务器:IP,端口port
www.baidu.com:域名 -> IP
DNS
对象读写
ObjectInputStream(字节流)
readObject()
ObjectOutputStream(字节流)
writeObject(obj)
对象 -> 字节:序列化
对象必须是可序列化的Serializable
异常:Exception — 都是可以解决
运行时异常/未检查异常:父类RuntimeException继承自Exception
ClassCastException -> 类型转换异常
NullPointerException -> 空指针异常
ArrayIndexOutOfBoundsException -> 数组越界异常
StringIndexOutOfBoundsException -> 字符串越界异常
ConcurrentModificationException -> 集合迭代删除异常
NumberFormatException -> 数值转换异常
Integer.valueof("aa")
造成的原因:程序员自身马虎,必须要解决的
已检查异常:父类Exception
FileNotFoundException -> 文件没有找到异常
IOException -> IO异常
ParseException -> 格式转换异常
SQLException -> 数据库异常
UnsupportEncodingException -> 不支持编码异常
ClassNotFoundException -> 类没有找到异常
不是程序员自身的问题,没有办法完全避免
可能是外部客观原因,不能彻底解决,只能避免
处理异常
只有已检查异常需要使用代码处理
未检查异常必须修改代码,纠正程序
1.方法上声明throws抛出异常
2.自己处理 try/catch 代码块
try中是可以正常执行的代码,但在异常出现之后的代码都执行不到
catch捕获到指定异常后执行的代码,可以理解为备用方案
注意:
try只能有一个,但是catch可以有很多,至少有一个,一个catch中可以捕获多个异常,用 | 连接
同一个异常不能多次捕获
捕获异常,可以使用父类异常捕获,但是如果同时捕获子类和父类们必须先捕获子类异常,后捕获父类异常
前期代码,很少使用异常处理
throw手动抛出异常对象
异常处理原则:能自己解决的尽量自己解决,不能解决的向外抛出,但总得解决
异常属性:message - 异常提示信息
所有异常都有一个传message初始化的构造器
所有异常都有getMessage()
面试:
throw和throws的区别
final是关键字、finalize是方法—Object是垃圾回收需要使用的、finally为无论如何一定会执行的语句块
通常用来释放资源
finally和return(return在try即finally前)谁先执行
按照代码的前后顺序,返回的是try当中保存的数据
自定义异常:
目的:为了区分不同的异常类型
定义方法:只需要添加构造器即可
其他全部靠继承
注解
@Before:在所有的Test方法之前运行
@After:在所有的Test方法之后运行
严重错误:Error
StackOverError
总结:
1.变量
局部变量 -> 必须需要初始化
成员变量 -> 有默认值
常量 -> 必须初始化
static final静态常量 -> 需初始化
2.变量类型
基本数据类型:8 通过二进制补码存储
byte、short、int、long、float、double、boolean、char
引用类型:除了基本数据类型全部都是,接口,类,枚举,注解,数组
3.运算符
++ -- :位置的区别
|| &&:一个和两个的区别(一个都要算)
?:三路运算
+= -=:赋值运算
^ ! :逻辑运算
>> >>>:移位运算,两个带符号
4.逻辑控制语句
If
If - else
If - else if … else …..
switch(int/String) - case
for
while
do - while
5.方法
声明、调用
返回值:向方法索要的结果
6.方法的重载:方法名相同,参数不同,返回值不同
方法的重写:子类才能重写父类,方法名相同,参数相同,返回值一样。
static与final不能重写,抽象方法可以重写
7.数组
基本数据类型的数组,默认都是0
引用类型数组,默认都是 null
数组没有初始化导致空指针问题
二维数组:数组中存了数组
8.类、对象
类型—概念
对象—实例化-个体
this()调用自己的构造器
9.父类,继承extends
Super(),构造器不能继承,只能调用
10.static:属于类的
final:最终的,不可变的
11.abstract 抽象类
Interface 接口,只有抽象方法和静态常量
JDK1.8特性:default默认方法
JDK1.8新特性:
lambda表达式
stream
12.内部类
匿名内部类 - 实现接口、继承抽象类
Comparator
FileFilter
成员内部类 - node
13.枚举
简化版的静态常量,没有具体指,只有字段名
用处:赋值、判断、分支
14.JavaSE
Object:toString、equals、hashcode
Wait * 3、notify、notifyAll
clone、finalize、getClass - 类加载
15.String:常量池
“hello” == "hello"
trim、split、startsWith、charAt、indexOf、substring
16.包装类
Integer常量池:-128~127
valueOf,parseInt、MAX_VALUE、MIN_VALUE
拆箱、装箱 - 对应方法
17.Date、long、Calendar(字段)
Set
Add
Get
三种格式之间的相互转换
格式化 - SimpleDateFormat
18.集合架构
Collection
List、Set、Queue
ArrayList、LinkedList、HashSet、TreeSet、Deque
Map
HashMap、TreeMap、ConcurrentHashMap、LinkedHashMap、Properties
泛型
迭代器Iterator - foreach,只能迭代,不能删除
Collections - 静态方法
19.IO