java - day016 - IO续(输入输出), 手写双向链表

  • 课程回顾
  • 对象的创建过程
    • 类加载
      • 加载父类,父类的静态变量分配内存
      • 加载子类,子类的静态变量分配内存
      • 父类静态变量赋值运算, 和静态初始化块
      • 子类静态变量赋值运算, 和子类初始化块
    • 创建对象
      • 创建父类对象, 父类的实例变量分配内存
      • 创建子类对象, 子类的实力变量分配内存
      • 父类的实例变量赋值,
      • 父类的构造方法
      • 子类的实例变量赋值
      • 子类的构造方法
  • 接口
    • 作用: 结构设计工具, 解耦合, 隔离实现
    • 本质上是一个抽象类
    • interface
    • implements
    • 接口可以实现多个
    • 接口之间也可以多继承
  • 内部类
    • 非静态内部类, 静态内部列, 局部内部类, 匿名内部类
    • 非静态内部类
      • 辅助外部对象, 来封装局部数据, 或者局部的运算逻辑
      • 非静态内部类的对象, 属于一个外部对象
      • 非静态内部类不能独立创建对象
      • A a = new A();
        Inner  i = a.new Inner();

        同类内部可以省略 a. 

 

 

 

  • ObjectInputStream / ObjectOutputStream
    • 对象的序列化和反序列化
    • 把对象的信息, 按照固定的字节格式, 转成一串字节序列输出
    • 方法
      • writeObject(object obj);
        • 序列化输出对象
      • readObject();
        • 反序列化恢复对象
    • 被序列化的对象必须实现 Serializable 接口
    • Serializable 
      • 空接口
      • 标识接口可以序列化
    • 不序列化的成员
      • static
        • 静态属于类, 不能用对象序列化
      • transient 
        • 临时
        • 只在程序运行期间,在内存中临时存在
    • 序列化版本
      • 控制旧版本的数据,不允许恢复新版本的类型
      • 自己不定义,编译器会添加默认版本 ID
        • 根据类的定义信息来产生版本 ID

 

 

  • 字符集. 字符编码
  • ASC-II,  最初字符集 
    • 0 到 127
    • 英文字符, 标点, 及指令字符
  • iso-8895-1 ,   Latin-1
    • 扩展到 255
  • cjk 字符集 , 中日韩字符集统称
    • 双字节编码 , 到 65535
  • 中国国标码 GBK
    • 包含 21003 个中文字符
  • Unicode 编码
    • 统一码, 万国码
    • 有 100 万+ 编码位
    • 常用字符表 - 双字节
    • 生僻字符表 - 三字节或以上标识
  • UTF-8
    • Unicode 的传输格式
    • Unicode Transfermation Format
    • 英文 - 单字节
    • 某些字符 - 双字节
    • 中文 -  三字节
    • 特殊符号 - 多字节

 

  • Java 的 char 类型字符, 使用Unicode 编码
  • Java的字符编码转换
    • Unicode <---> 其他编码
    • Unicode --> 其他编码
    • String s = "abc中文";
      // Unicode 转成系统默认编码
      byte[] a = s.getBytes();
      // 转成指定的编码
      byte[] a = s.getBytes("UTF-8");

       

    • 其他编码 --> Unicode
    • // 把系统默认编码的一组字节值, 转成 Unicode
      String s = new String(byte[]);
      // 把指定编码的一组字节值, 转成 Unicode
      String s = new String(byte[], "UTF-8");

       

 

 

  • Reader / Writer
  • 字符流, 抽象类
    • 方法
      • write(int c); //
        • int 四个字节, 末尾两个字节是 char 类型字符数据
        • 只处理末尾两个字节的输出
      • write(char[] , from , length);
        • 输出 char 数组中 , from 开始的 length 长度的数据
      • write(String s);
        • 输出字符串的全部字符
    • package day1604_编码转换;
      
      import java.io.UnsupportedEncodingException;
      import java.util.Arrays;
      
      public class Test1 {
          public static void main(String[] args) throws UnsupportedEncodingException {
      
              
              String s = "abc中文";
              
              System.out.println(s);
              
              f(s,null);
              f(s,"GBK");
              f(s,"UTF-8");
          }
      
          private static void f(String s, String charset) throws UnsupportedEncodingException {
              
              // 字符串 s, 转成其他编码的一组字节值
              byte[] a;
              if (charset == null) {
                  
                  a = s.getBytes();
              }else {
                  a = s.getBytes(charset);
              }
              
              System.out.println(charset + "\t"+Arrays.toString(a));
              
              
              // 从默认编码转回 Unicode
              // 从指定的编码转回 Unicode
              
              String str;
              if (charset == null) {
                  str = new String(a);
              }else {
                  str = new String(a, charset);
              }
              
              System.out.println(str);
          }
      }

       


 

  • 子类 InputStreamReader / outputStreamWriter
    • 字符编码转换流
    • InputStreamReader
      • 读取其他编码转成 Unicode
    • outputStreamWriter
      • 把Unicode 转成 其他编码输出
    • package day1605_编码转换流;
      
      import java.io.FileOutputStream;
      import java.io.OutputStreamWriter;
      
      public class Test1 {
          public static void main(String[] args) throws Exception {
      
              f("/Users/dingzhijie/Desktop/file2.txt","abc中文丁志杰","GBK");
              f("/Users/dingzhijie/Desktop/file3.txt","abc中文丁志杰","UTF-8");
              
          }
      
          private static void f(
                  String path,
                  String s,
                  String charset) throws Exception {
              
              FileOutputStream fos = new FileOutputStream(path);
              OutputStreamWriter osw = new OutputStreamWriter(fos,charset);
              
              
              osw.write(s);
              
              osw.close();
              
          }
      }

       


 

  • BuffereadReader
    • 可以一行一行读取文本数据
    • readLine();
      • 读取一行数据
      • 读取结束,再读取返回 null
    • package day1606_Buffereader;
      
      import java.io.BufferedReader;
      import java.io.FileInputStream;
      import java.io.InputStreamReader;
      
      public class Test1 {
          public static void main(String[] args) throws Exception {
      
              String path = "/Users/dingzhijie/Desktop/file6.txt";
              String charset = "GBK";
              
              
              
              FileInputStream fis = new FileInputStream(path);
              InputStreamReader ips = new InputStreamReader(fis,charset);
              BufferedReader br = new BufferedReader(ips);
              
              
              String line;
              while ((line = br.readLine()) != null) {
                  System.out.println(line);
              }
              
              br.close();
              
          }
          
          
      }

       


  • 手写双向链表
  • package day1501_手写双向链表;
    
    import java.util.Iterator;
    
    //  链表类
    public class SXLianBiao<T> implements Iterable<T>{
        
        private Node first; // 头部节点, 初始 null
        private Node last;  // 尾部节点, 初始 null
        
        private int size;   // 节点数量,初始值 0
        
        
        public void add(T value) {
            
            Node n = new Node();
            n.value = value; //  数据封装到 n
            
            if (size == 0) { // 添加第一个node 对象
                n.prev = n;      //  n向前引用n
                n.next = n;      //  n向后引用n
                
                this.first = n;  // n 是头部节点
                this.last = n;   // n 也是尾部节点
                
            }else {
                n.prev = this.last;
                n.next = this.first;
                this.last.next = n;
                this.first.prev = n;
                this.last = n;
                
            }
            
            this.size++;
        }
        
        public T get(int index) {
            
            
            Node n = getNode(index);
            
            return n.value;
        }
        
        private SXLianBiao<T>.Node getNode(int index) {
            // i越界
            // 取头尾
            // 取中间
            
            if (index < 0 || index >= this.size) {
                throw new IndexOutOfBoundsException(""+index+"越界");
            }
            
            if (index == 0) {
                return this.first;
            }else if (index == this.size-1) {
                return this.last;
            }
            
            
            Node n = null;
            
            if (index < this.size/2) { // 前边一半
                // n 引用first
                n = this.first;
                // 从 j 到 index
                for (int j = 1; j < index; j++) {
                    n = n.next;
                }
                
                return n;
                
            }else { // 后面一半
                n = this.last;
                for (int j = this.size-2; j >= index ; j--) {
                    n = n.prev;
                }
            }
            
            return n;
        }
    
        public int size() {
            return size;
        }
        
        // 内部类, 封装节点数据
        // 节点类,辅助外部双向链表对象
        // 来封装局部数据
        private class Node{
            T value;     // 节点中封装的数据
            Node prev;   // 引用前一个节点对象
            Node next;   // 引用后一个节点对象
        }
        
        
        // Iterable 的抽象实现方法
        public Iterator<T> iterator(){
            return new Itr();
        }
        
        
        // 迭代器类
        // 内部类,封装双向链表的局部运算逻辑
        private class Itr implements Iterator<T>{
    
            Node n = null;
            
            @Override
            public boolean hasNext() {
                
                if (size == 0) {
                    return false;
                }
                
                // 回到 first, 标识没有更多数据
                return n != first;
                
            }
    
            @Override
            public T next() {
                if (n == null) {
                    n = first;
                }
                T value = n.value; // 取当前节点的数据
                n = n.next;// 让 n 指向下一个节点
                return value; // 返回数据
            }
            
        }
        
        
        
        
        
        
        
    }

     

 

posted @ 2019-07-28 16:20  Dingzhijie  阅读(300)  评论(0编辑  收藏  举报