集合:
3.1 collection:集合框架的顶级接口
--List:接口,有序且允许重复的
--ArrayList:底层数据结构是数组,查询快,增删慢。线程不安全,效率高。
–Vector:底层数据结构是数组,查询快,增删慢。 线程安全,效率低。
–Vector相对ArrayList查询慢(线程安全的)
–Vector相对LinkedList增删慢(数组结构)
–LinkedList:底层数据结构是链表,查询慢,增删快。线程不安全,效率高。
–Vector和ArrayList的区别
--Vector是线程安全的,效率低
--ArrayList是线程不安全的,效率高
–共同点:都是数组实现的
–ArrayList和LinkedList的区别
--ArrayList底层是数组结果,查询和修改快
--LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
–共同点:都是线程不安全的
--set:接口,无序且不允许重复
--HashSet:子类,无序的Set,底层实现是基于散列算法,散列存储 (常用)
--TreeSet:子类,有序的Set,底层实现是二叉树算法实现 (不常用)
3.2 Map<key,value>:集合框架的顶级接口
Map是键值对的形式存取数据
–HashMap<key,value>:子类,无序的Map,底层实现是基于散列算法,散列存储,度是针对key的操作 (常用)
--TreeMap:子类,有序的Map,底层实现是二叉树算法实现,度是针
对key的操作
3.3Collections:类
集合工具类,里面封装了很多针对集合操作的方法(类似于Arrays)
它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架。
3.4泛型和通配符
A:泛型好处
.提高安全性(将运行期的错误转换到编译期)
.省去强转的麻烦(如果集合不加泛型,默认存储的是Object类,即是存储进来的都会事先转为Object)
B:泛型基本使用
.<>中放的必须是引用数据类型,也就是说普通数据类型必须使用包装类
C:泛型使用注意事项
.前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
.集合了指明的泛型类之后,迭代器Iterator就必须是该泛型类(该泛型类的父类以及子类都不可以),一句话:指定了什么类型就是什么类型,他父亲儿子都不可以替代他
.方法泛型最好与类的泛型一致(这样与类泛型相同的类内方法可以不写泛型了),如果不一致,需要在方法(静态方法必须声明自己的泛型,写在static关键字之后)上声明该泛型,格式:public <泛型类型> 返回类型 方法名(泛型类型 变量名),
D:通配符使用的场景
.方法的形参!
E:通配符的优点
.使方法更加通用!
F:通配符分类
.无界通配:?
.子类限定:? extends Object
.父类限定:? super Integer
G:通配符缺点
.使变量使用上不再方便
.无界:参数和返回值为泛型的方法,不能使用!
.子类:参数为泛型的方法不能使用
.父类:返回值为泛型的方法不能使用
四 IO流:
IO流:输入输出流 (InputStream,OutputStream)
概念:参照物都是内存
例如:集合中的数据写到文件里面 (内存–>硬盘) 输出流
读取Excel表格里面的数据到集合 (硬盘–>内存) 输入流
4.1字节流(基本流):每次读取1个字节
1)适合于:读取非文本类型的数据(*.exe,图片,视频,音频等)
InputStream, OutputStream 都是抽象类
InputStream 抽象了应用程序读取数据的方式
OutputStream 抽象类应用程序写出数据的方式
EOF = End of File = -1
A:输入流基本方法:
int b = in.read() 读取一个byte 无符号填充到int低八位,-1是EOF
in.read(byte[] buf) 读取数据填充到buf中
in.read(byte[] buf, int start, int size)读取数据填充到buf中
in.skip(long n)
in.close();
B:输出流的基本方法:
out.write(int b) 写出一个byte到流 b的低八位写出
out.write(byte[] buf) 将缓冲区buf都写入到流
out.write(byte[] buf, int start, int size)将buf的一部分
C:写到流中.
out.flush() 清理缓冲
out.close();
InputStream OutputStream
文件(Byte 序列) --输入流–> 应用程序 --输出流–> 文件(Byte)
in.read() out.write()
2)文件输入流 FileInputStream 继承了InputStream
FileInputStream 具体实现了在文件上读取数据
任务1: 读取文件并且按照HEX输出, 每10 byte为一行
3)文件输出流 FileOutputStream 继承了OutputStream
FileOutputStream 实现了向文件中写出byte数据的方法
4)BufferedInputStream 和 BufferedOutputStream
一般打开(in/out)文件, 都加上缓冲流, 提高IO性能
DOS BOS FOS
应用程序 – 过滤器–>过滤器–>输出流–> 文件(Byte)
writeInt(i) write() write(byte[]) ff ff ff fd
byte[]
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream in = new DataInputStream(bis);
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream out = new DataOutputStream(bos);
5)文件复制实现与优化
InputStream OutputStream
文件(Byte 序列) --输入流–> 应用程序 --输出流–> 文件(Byte)
in.read() out.write()
4.2字符流:每次读取1个字符 Reader Writer
适合于:读取文本类型的数据(*.txt等)
Reader和Writer都是抽象类
Reader:抽象了应用程序读取数据的方式
Writer:抽象了应用程序写出数据的方式
InputStreamReader:Reader的子类,输入字符流
OutputStreamWriter:Writer的子类,输出字符流
FileReader:InputStreamReader的子类,按字符读取
FileWriter:OutputStreamWriter的子类,按字符输出
FileWriter继承的Writer类中有一个2k的小缓冲区,如果不关流,就会将内容写到缓冲区里,关流会将缓冲区内容刷新,再关闭
BufferReader:带缓冲的输入字符流
BufferWriter:带缓冲的输出字符流
读取的时候是按照字符的大小读取的,不会出现半个中文
写出的时候可以直接将字符串写出,不用转换为字节数组
A:输入流基本用法:
FileReader fileReader=new FileReader(file);
InputStreamReader in=new InputStreamReader(new FileInputStream(file));
BufferedReader buff1=new BufferedReader(in);
BufferedReader buff2=new BufferedReader(fileReader);
in.read();
buffer1.read();
buffer2.read();
in.close();
buffer1.close();
buffer2.close();
B:输出流基本用法
FileWriter fileWriter=new FileWriter(file);
OutputStreamWriter os=new OutputStreamWriter
(new FileOutputStream(file));
BufferedWriter bw1=new BufferedWriter(os);
BufferedWriter bw2=new BufferedWriter(fileWriter);
一般打开(in/out)文件, 都加上缓冲流, 提高IO性能
DOS BOS FOS
应用程序 – 过滤器–>过滤器–>输出流–> 文件(Byte)
4.3对象流:每次读写一个对象类型的数据
ObejctInputStream
ObjectOutputStream
当使用对象流写入或者读取对象的时候,必须保证该对象是序列化的,这样是为了保证对象能够正确的写入文件,并能够把对象正确的读回程序。
所谓的对象的序列化就是将对象转换成二进制数据流的一种实现手段,通过将对象序列化,可以方便的实现对象的传输及保存。在Java中提供了ObejctInputStream 和ObjectOutputStream这两个类用于序列化对象的操作。用于存储和读取对象的输入输出流类,要想实现对象的序列化需要实现Serializable接口,但是Serializable接口中没有定义任何的方法,仅仅被用作一种标记,以被编译器作特殊处理。
4.4 字符串的序列化(文字的编码方案)
- Stirng 字符串本质上是char[] 将char[] 转换成byte序列
就是字符串的编码, 就是字符串的序列化问题
char是16位无符号整数, 值是unicode编码
- utf-16be 编码方案, 将16位char从中间切开为2个byte
utf-16be 是 将unicode char[] 序列化为byte[] 的编码方案
能够支持65535 个字符编码, 英文浪费空间
char[] = [‘A’,‘B’,‘中’]
byte[] = [00, 41, 00, 42, 4e, 2d]
- UTF-8 编码方案 采用变长编码 1~N方案, 其中英文1个byte
中文3个byte