本帖最后由 wlxHeiMa追梦 于 2018-8-7 17:30 编辑
Lambda、IO流、File类、缓冲流和序列化流等 序列化流(对象流) 1. 序列化流分为两种 : 序列化和反序列化 1.1 什么是序列化? 把对象以流的方式写入到文件中保存,叫做对象的序列化,也可以叫做写对象.对象被写入到文件中保存,因为对象中包含的不仅仅是字符,也可以包含视频.音频.文件.等等,所以文件中存储的形式统统为字节形式. ObjectOutputStream : 对象的序列化流 1.2 什么是反序列化? 磁盘文件中的字节序列, 以流的方式读取到内存中变成对象字节转对象.把文件中保存的对象,以流的方式读取出来,叫做对象的反序列化,也叫做读对象.因为文件中保存的对象都是以字节形式保存的,所以用字节流读取. ObjectInputStream :对象的反序列化流 一. ObjectOutputStream类(对象字节输出流) 定义.使用格式.包含方法.方法使用场景 OutputStream的子类 : 概念 : ObjectOutputStream类(对象字节输出流): : 将Java对象的原始数据类型写出到文件,实现对象的持久存储 创建一个指定OutputStream的ObjectOutputStream 序列化的具体操作步骤 : 1. 一个对象如果想要被序列化, 必须满足两个条件: 1.1 :该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException异常 。注意事项 : 没有序列化异常 1.2 : 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。 编程单词汇总 : (1) : close 关闭 (2) : address 地址 (3) : Stream : 流 (4) : write : 写 (5) : final : 最终的 (6) : read : 阅读 (7) : Stack : 栈 (8) : Object : 对象 (9) : InputStream : 输入流 (10) : readobject : 读取对象 (11) : getname : 获得名称 (12) : getAge : 获得年龄 InputStream的子类 : ObjectInputStream类: 对象字节输入流: ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。 反序列化操作 : 如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream 读取对象的方法 public final Object readObject () : 读取一个对象。 反序列化的前提 : 1. 类必须实现Serializable 2.必须存在类对应的class文件 【File类、递归】 一 File类 1.1概述 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 注 : File : 把路径名用String字符串的形式表现了出来. 1.2 构造方法 public File(Stringpathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 public File(Fileparent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。 问题汇总: 1. 什么是绝对路径? 回答: 从盘符开始,路径一直到所选择的文件名称. 2. 什么是相对路径? 回答: 所选择的文件名称或者文件名相对于上一个文件夹名. 这个所选择的文件名称就是相对路径. 3. 什么是父子路径? 回答: 在一个完整路径中,从哪里截取,在完整路径中截取的前半段就是父路径,截取的后半段就是子路径. 注意事项: 1. 文件返回的大小,用字节数表示(int 数字).文件有具体的大小,文件夹没有,所以返回的结果是0(不能获取目录的大小) 2. 一个File对象代表硬盘中实际存在的一个文件或者目录. 3. 无论该路径下是否存在文件或者目录,都不影响File对象的创建 1.3 常用方法 判断功能的方法 : public boolean exists():此File表示的文件或目录是否实际存在。 public booleanisDirectory() :此File表示的是否为目录。 public boolean isFile():此File表示的是否为文件(不要与文件夹混淆,只是文件)。 创建删除功能的方法: public booleancreateNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。 public boolean delete():删除由此File表示的文件或目录。 public boolean mkdir() :创建由此File表示的目录??? public boolean mkdirs():创建由此File表示的目录,包括任何必需但不存在的父目录????. 1.4 目录的遍历 public String[ ] list():返回一个String数组,表示该File目录中的所有子文件或目录。 public File[ ]listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。 区别在于: list只打印当前的文件或文件夹名称 listFiles打印完整的路径名称,从盘符开始.
【递归】
递归概述: 递归:指在当前方法内调用自己的这种现象。 递归的分类: 递归分为两种,直接递归和间接递归。 直接递归称为方法自身调用自己。 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。 注意事项: 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。 构造方法,禁止递归 递归是我们编程思想中很重要的一部分,今天我以一些小案例,简单介绍一下递归的使用(数学逻辑推导). 描述: 猴子吃桃子问题(改编版),猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天又将仅剩下的桃子吃掉了一半,又多吃了一个。以后每天都吃了前一天剩下的一半多一个。到第n天,只剩下一个桃子。试求第x(x<n)天共有多少桃子? 一、分析: 从描述中我们可以得出以下几个结论: 1. x天剩下的桃子,即x天的桃子数; 2. 假设x天桃子数为S,那么从描述中可得:S(n)=1; 3. 从描述中得出规律:S(n-1)=[S(n)+1]*2,S(n-2)=[ S(n-1)+1]*2 ……S(x)=[S(x+1)+1]*2 二、从分析得计算数学公式: S(x)=[S(x+1)+1]*2 file:///C:/Users/29316/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png 三、编程步骤: 1. 从分析可以看出,我们需要键盘键入两个变量:x和n; 2. 定义一个方法(含两个参数x和n),进行递归调用 3. 传入x和n,得出结果 四、示例代码如下: [Java] 纯文本查看 复制代码 public class PeachDiGuiTest01 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入剩下一个桃子的天数");
int n=sc.nextInt();
System.out.println("要想计算第x天剩下的桃子,请告诉我x:");
int x = sc.nextInt();
int result=getPeachSum(n,x);
System.out.println(result);
}
private static int getPeachSum(int n,int x) {
if(x==n){
return 1;
}
return (getPeachSum(n,x+1)+1)*2;
}
}
五、总结:递归简单来说:从编程角度说:就是自己调用自己。从数学角度说:就是从已知推出未知的过程。递归之所以重要,就是因为它可以推出未知,毕竟生活中,未知远大于已知,因此,递归思想就越发显得重要。六、附加代码这是一些比较简单的使用递归的代码,方便我们更好的理解递归。
1) 递归求和(1-100)
[AppleScript] 纯文本查看 复制代码 public class DiGuiDemo {
public static void main(String[] args) {
//计算1~num的和,使用递归完成
int num = 100;
// 调用求和的方法
int sum = getSum(num);
// 输出结果
System.out.println(sum);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getSum(int num) {
/*
num为1时,方法返回1,
相当于是方法的出口,num总有是1的情况
*/
if(num == 1){
return 1;
}
/*
num不为1时,方法返回 num +(num‐1)的累加
递归调用getSum方法
*/
2)递归求阶乘(5!)
[Java] 纯文本查看 复制代码 public class DiGuiDemo {
[/color][/font]
[font=微软雅黑][color=black] //计算n的阶乘,使用递归完成
public static void main(String[] args) {
int n = 5;
// 调用求阶乘的方法
int value = getValue(n);
// 输出结果
System.out.println("阶乘为:"+ value);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getValue(int n) {
// 1的阶乘为1
if (n == 1) {
return 1;
}
/*
n不为1时,方法返回 n! = n*(n‐1)!
递归调用getValue方法
*/
return n * getValue(n ‐ 1);
}
}
3)文件搜索
[Java] 纯文本查看 复制代码 public class DiGuiDemo3 {
public static void main(String[] args) {
// 创建File对象
File dir = new File("D:\\aaa");
// 调用打印目录方法
printDir(dir);
}
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
for (File file : files) {
if (file.isFile()) {
// 是文件,判断文件名并输出文件绝对路径
if (file.getName().endsWith(".java")) {
System.out.println("文件名:" + file.getAbsolutePath());
}
} else {
// 是目录,继续遍历,形成递归
printDir(file);
}
}
}
}
IO流 一.什么是IO流? (1) : 输入(In) (2) : 输出(Out)流 (3) : 流: 数据流 作用 : 输入(In): 把数据从硬盘读取到内存 输出(Out) : 把数据从内存读取到硬盘 (这里的入和出都是相对于内存来说的) 二.IO流的分类 总共分为两类: 字节流 和 字符流 2.1 字节流 : 读写字节: byte, 可以读写所有类型的文件,包括视频, 图片, 音频, 文本等 字节流分为两个类: 字节输入流 :java.io.InputStream 抽象类 字节输出流 :java.io.OutputStream 抽象类 2.2 字符流 : (读写字符: char,String, 只能读写文本文件) 字符流分为两个类: 字符输入流: java.io.Reader 抽象类 字符输出流: java.io.Writer 抽象类 三.字节流 基本常识: 计算机中的一切皆为字节. 计算机中, 无论文本, 视频, 音频, 图片...一切都是以"字节byte"形式存储的 也就是以数字形式存储的, 而数字可以用不同进制表示,计算机能看懂的是二进制数字. 3.1 字节输出流: OutputStream和FileOutputStream java.io.OutputStream抽象类:字节输出流 (顶层类) : OutputStream 内包含五个成员方法,其中五个成员方位分为两类: 成员方法及写字节的成员方法 成员方法 (包含两个): (1) : close : 释放资源.一般在方法代码末尾. (2) : flush : 刷新缓冲区(对于字节流来说没有任何作用) 写字节的成员方法(包含三个) : (1): abstract void write(int b): 一次写一个字节 (参数是int是为了代码中写表示byte的整数方便不用强转) (2): void write(byte[] b): 一次写一个字节数组 (3): void write(byte[] b, int off, int len): 一次写一个字节数组的一部分 字节输出流 : 一次写一个字节到文件 Java程序将数据写入文件的原理 : Java程序 -> JVM虚拟机 -> OS操作系统 -> OS调用写数据的方法 -> 将数据写入文件 使用字节输出流写数据到文件的步骤(一共为三步) 1. 创建对象: 创建FileOutputStream对象, 构造方法中传递文件路径 2. 写入数据: 使用FileOutputStream对象调用write(int b) 方法, 将字节写入文件 3. 释放资源: 使用FileOutputStream对象调用close() 方法, 关闭流对象释放资源
文件存储原理和记事本打开文件的原理 基本常识 : (1) 向文件中写入字节数据时, 写入的是什么进制的数据? 向文件中写入字节数据时, 十进制的数字会被转换为"二进制"的数字写入文件.计算机能看懂的是二进制数字. (2) 写入文件的是数字, 但文本编辑器打开后为什么会显示为字符? 文本编辑器打开文本文件时, 会先查询编码表, 将二进制数字转换为对应的字符进行显示 0-127: 查询ASCII码表 其他: 查询系统默认码表 Windows简体中文系统的程序打开是按GBK 码表 IDEA中使用的是 UTF-8 码表 ASCII编码表: 1个byte就是一个字符 GBK编码表: 2个byte数字组成一个汉字."你": -60, -29 UTF-8编码表: 3个byte数字组成一个汉字."你": -28, -67, -96
字节输出流: 一次写多个字节 java.io.FileOutputStream类:文件字节输出流 (向文件写数据) void write(byte[] b): 一次写一个字节数组 void write(byte[] b,int off, int len): 一次写一个字节数组的一部分 重点 : java.lang.String类: byte[] getBytes(): 使用平台的默认字符集将此String编码为byte数组. 使用当前编译平台的默认字符集将String类型的数据用byte数据类型表达出来. 什么是字符集? 字节输出流: 续写操作 (1) 什么是续写操作? 在文件已有内容之后, 接着写入内容 (续写). (2) 如何在文件中写入换行, Windows系统的换行符号是什么? 换行符: Windows系统:"\r\n" Linux系统: "\n" MacOS系统: "\r" 带有 "续写" 功能的构造方法,不会清空文件 FileOutputStream(Stringname, boolean append): 通过文件路径创建文件字节输出流, true可以续写 FileOutputStream(Filefile, boolean append): 通过File对象创建文件字节输出流, true可以续写
|