>>>First:
递归!
1. 定义: 在函数自身内部, 调用函数本身的方式, 称为递归.
2. 注意: 递归包括递进去, 归出来两步.
首先, 依次执行 [函数调自身语句] 上半部分的代码, 直到最里层;{ 递进去 }
然后, 再从最里层开始, 依次执行 [函数调自身语句] 下半部分的代码.{ 归出来 }
3. 下面用示意图来分析一下:
!!! 递归必须通过合适的语句, 及时的跳出, 否则容易造成死循环.
4. 用一个例子帮助你理解递归的用法:
用递归实现一个数的阶乘
首先, 定义一个 jiecheng 类:
方法一:
方法二:
其次, 在 main 方法中输出:
运行验证: 以 5 的阶乘为例输出结果
以上便是关于递归的基础知识, So easy, 看到这想必就已经学会了! 再来看一下今天下一个主角:
>>>Second:
IO 流
1,I/O 流分类:
根据流的方向: 输入流和输出流
根据读取文字的大小: 字节流和字符流
(字节流按字节读取, 读取中文时容易乱码; 字符流按照字符读取, 通常用于读取中文)
根据读取的方式: 节点流和缓存流
2, 读取文件内容:(3 种方法 )
- FileInputStream fis = new FileInputStream("F:/test.txt");
- StringBuffer sb = new StringBuffer();
按照字节, 一个一个字节读取文件
将 byte 数组直接声明为输入流的长度, 一次性读出所有文字
一次性读取 1024 个字节
3, 写入新文件:
// FileOutputStream fos = new FileOutputStream("F:/out.txt",true);
如果第二个参数省略, 或传入 false, 则表示每次写入时将原文件清空, 从文件头部开始写入;
如果第二个参数传入 true, 则表示不清空原文件, 在文件末尾处添加新内容.
FileOutputStream fos = new FileOutputStream("F:/out.txt");
首先, 读取文件内容 (见上), 然后写入:
4, 捕获异常
(有关异常的内容还有很多, 在这就先不详解了)
读写文件时, 易出现异常, 故, 需要在读写过程中进行异常处理, 例如捕获异常
- try{
- FileInputStream fis = new FileInputStream("F:/test.txt");
- FileOutputStream fos = new FileOutputStream("F:/out.txt");
- StringBuffer sb = new StringBuffer();
- // 读取文件
- int n = -1;
- while((n=fis.read()) != -1){
- sb.append((char)n);
- }
- System.out.println(sb);
- sb.reverse();
- fos.write(sb.toString().getBytes());
- System.out.println(sb);
- } catch(FileNotFoundException e){
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- 5,BufferedInputStream / BufferedOutputStream
作用: 在基本流的基础上进行包装, 读取或者写入文件时, 将通过缓存进行.
即, 先将内容写入到缓存区, 缓存区满以后, 再进行读取或者写入操作.
可以大大减少文件的操作次数, 提高写入效率.
缓存流的使用
在基本流的基础之上, 进行包装:
new BufferedInputStream(new FileInputStream("F:/test.txt"));
这种写法. 我们称之为 IO 链, IO 关闭时, 只需要关闭最外层流, 内层流将自动关闭.
BufferedOutputStream 在关闭前, 通常调用 bos.flush();
表示关闭前将缓存进行刷新, 将缓存区剩余未满的内容写入文件.
但是, 一般. close() 方法, 自带刷新功能.
代码示例:
6,DateInputStream / DateOutputStream
采用二进制对文件进行读写操作.
与基本流相比, 可以直接读写 java 中的基本数据类型.
另外, 如果操作的文件是一个二进制文件, 需要使用 DataOutputStream 替代 FileOutputStream.
同样, Date 系列的流, 也有 read 和 write 方法, 操作与基本相同.
注意: 只用 DataOutputStream 写入文件为二进制文件, 只能使用 DataInputStream 进行读取.
- String name = "zhangsan";
- int age = 12;
- double height = 178.5;
- String ads = "山东烟台";
- DataOutputStream dos = null;
- DataInputStream dis = null;
- try {
- dos = new DataOutputStream(new FileOutputStream("F:\\zhangsan.txt"));
- dos.writeUTF(name); dos.writeInt(age);
- dos.writeDouble(height);
- dos.writeUTF(ads);
- dis = new DataInputStream(new FileInputStream("F:\\zhangsan.txt"));
- String uname = dis.readUTF();
- int uage = dis.readInt();
- double uheight = dis.readDouble();
- String uads = dis.readUTF();
- System.out.println(uname+"---"+uage+"---"+uheight+"---"+uads);
- } catch(FileNotFoundException e){
- e.printStackTrace();
- }catch (IOException e) {
- // TODO: handle exception
- e.printStackTrace();
- } finally{
- try {
- dis.close();
- dos.flush();
- dos.close();
- } catch (IOException e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- }
- 7,ObjectOutputStream / ObjectInputStream
直接继承自: java.io.OutputStream 抽象类
与基本流相同, 可以使用 read,write 方法进行读写.
与 DateInputStream 相同, 可以对 Java 基本数据类型进行直接读写: readInt() writeDouble()
可以只用 readObject() 和 writeObject() 直接对对象进行操作.
[对象的序列化和反序列]
对象的序列化: 将程序中的对象, 持久化的保存在文件中的过程; ObjectOutputStream
对象的反序列化: 将文件中保存的对象, 重新读取到程序中的过程. ObjectInputStream
如果, 要将对象进行序列化操作, 那么实体类必须实现可序化接口.
class Person implements Serializable{}
注意: 当一个实体类, 实现可序化接口后, 可以添加一个序列化版本号 ID.
(实现序列化接口以后, 根据警告提示, 选择: Add default serial version ID.)
添加以后, 可以用 ID 表示序列化和反序列化时操作的对象, 是同一个对象.
会自动生成一个静态属性:
private static final long serialVersionUID = 1L;
如果不添加版本 ID, 给序列化一个对象后, 如果实体类对象有增删, 再进行反序列化时, 会造成错误.
因为系统认为这已经不是一个类.
+get,set 方法, 并重写 toString 方法.
来源: https://www.cnblogs.com/zyp777/p/8906143.html