序列化:把内存中 的对象通过序列化流输出到磁盘中(比如文件里),使用的流是ObjectOutputStream
反序列化:通过反序列化流将磁盘中的数据恢复成对象,使用的流是ObjectInputStream
对象–>只有运行程序的时候才有
程序不运行不能产生对象
最核心:保存对象
↓
对象不写在文件里,只有每次运行代码才产生对象
new Student()---->不运行不会产生对象,只是一堆字
序列化流:1.把对象保存下来
2.保存在文件里后,就可以发送了
序列化与反序列化的作用:对象的保存和传输
要序列化的对象所属类,标记上Serializable接口(一个空接口,和@Override,效果类似),固定搭配不写报错
↓
读作:实现可序列化接口
接口不是类
序列化时会生成一个UID表示当前序列化输出对象的版本信息,反序列化时会拿着当前的UID与之前
序列化输出的UID做比较,一致,反序列化成功,不一致,报错.
↓
所以,标准操作:【一次】序列化对应【一次】反序列化(UID一致)或手动设置,
如果目标对象所在类没有任何修改,一次序列化也可以对应多次反序列化
Object o = in.readObject();
System.out.println(o)
用Object接是因为readObject()读出的类多种多样
System.out.println(in.read);也行
Object类里有toString()方法,默认原始打印的是对象地址值,默认重写为打印对象属性值
反序列化是返回内存中,并没有改变硬盘里的文件.
-----------------------------------这个过程就是序列化-----------------------------------
【一个普通类对象(作为参数)】---->【序列化流对象调用方法(参数是普通类对象)】---->【写入目标地址文件】
文件地址.writeObject(普通对象);
-----------------------------------这个过程就是反序列化-----------------------------------
【一个文件地址】---------------->
普通类 普通对象 = 文件地址.readObject();
##############################################################################
集合Collection也可以存放多个数据
集合使用比数组更灵活,且提供丰富的方法来操作集合中的元素
泛型通常与集合一起用,用来约束集合中元素的类型
泛型不能写基本类型
泛型方法 public static void get(E() e){}
↓
关键就是一个E
泛型参数:一个广泛的类型,不管传什么类型,都能匹配到
方法参数重点在类型
形参:比如方法中参数列表里的参数名
这是一个局部变量,只能在当前方法里使用,所以方法的参数类似于一个中转站,
接收的是调用方法时传过来的参数值,然后执行方法时,使用这个传过来的值,方法结束释放
实参:实际的参数,有自己实际的值,比如变量int age = 18;
#############################################################################
泛型在编译的时期有(生存周期仅存在编译过程,编译好类型检查完就消失了),
编译生成的.class字节码文件里没有,所以不会影响JVM运行性能
Java应用程序的打包和发布???
##############################################################################
接口和类同属于java数据类型的引用数据类型,他们是同等级的,接口并不是类
##############################################################################
List—有序的Collection-----序列------内部存的数据都可以根据位置来操作
特点:
1.元素都有下标
2.数是有序的
3.允许存放重复的元素
所以List中元素是可以重复的.
List常用方法
学习新的接口
↓
从父接口的公共方法
入手
list相对于它的父接口Collection关键在于–使用索引
int数字元素,
必须int转Integer才能在remove()方法中不使用根据索引删除
转而使用根据元素删除
包装类手动装箱–>高效的Integer i1 = new Integer(5);
ListIterator–>在Iterator基础上还能倒着遍历
属于List接口特有的迭代器
############################################################################
ArrayList:底层是数组结构
存在java.util包中
内部是用数组结构存放数据,封装数组的操作,每个对象都有下标
内部数组默认的初始容量是10,如果不够会以1.5倍的容量增长
查询快,增删数据效率会低
数组查询–>快速定位
数组增删–>新做一个数组,全体搬家
LinkList
↓
底层
↓
链表 结构
来实现
越接近两端效率越高(遍历数序号),可以通过改指针快速增删元素
ArrayList
底层的数据结构是数组,增删操作比较慢,查询操作比较快,元素有下标
LinkList—实现类,可以直接new对象 List才是接口
底层的数据结构是链表,增删操作比较快,查询操作比较慢,元素有下标
注意:我们这里所说的"块"和"慢"是建立在数量比较大的情况下
注意:LinkList查询慢也不是都慢,首尾操作还是比较快的
注意:LinkList也是List序列的实现类,所以它的元素也是有下标的,也可以根据元素下标对元素做操作(不常用),
只不过常用首尾操作而已
注意:ArrayList底层数组的内存空间是连续的,
LinkList底层链表的内存空间是不连续的,靠着节点之间的地址值相连
链表元素:(2个部分)
1.元素值
2.一个地址
*.自带的下标
链表元素在内存空间不是连续的
API工具里看返回类型是不是void就可以确定能不能打印
##############################################################################
…:地址
节点[..|data|..]
头结点[NULL|data|…] 尾结点[…|data|null]
set结构一般用于去重,用到了map
MAP里的数据都是一对一对的
KEY----VALUE
所以也称为键值对
,即
Entry<K,V>-------------键值对--------------KEY和VALUE
键与值是一一对应的关系,可以根据KEY取到对应的VALUE
注意:KEY不允许重复,重复的话新的值会把旧的值覆盖
[法一]
map的Keyset()方法–>向set靠拢—为了迭代(map自己没有迭代功能)
取出key返回为一个set集合,随着迭代借助map.getKEY()联系value
[法二]
entryset()方法—把每个键值对视作一个元素,整体做出一个set集合,再迭代.
Set<Map.Entry>
泛型套泛型
因为Entry在Map的肚子里,是一个Map的内部类,outer.inner才能调用他(a的inner还是b的inner)
##############################################################################
OS一次删除操作底层进行了多次循环判断(文件夹,空文件夹,纯文件)
map集合的迭代
法一:
通过SET集合提取KEY
在MAP里提取对应VALUE
循环打印
法二:
把<键值对>作为泛型约束/类型
直接在SET类型里同时对<键值对>进行提取
循环打印
##############################################################################