zoukankan      html  css  js  c++  java
  • Java基础 IO流——第四部分

     

    新博客地址:Temi

    第一讲:IO流(对象的序列化)

    一,对象序列化的概念:将堆内存中的对象存入硬盘,保留对象中的数据,称之为对象的持久化(或序列化)。

                   ========被序列化对象必须实现 Serializable 接口,接口Serializable中没有方法,称之为标记接口===========

    ==============静态成员,和被transient 修饰的成员无法被序列化。静态成员属于类级别的,所以不能序列化这里的不能序列化的意思,是序列化信息中不包含这个静态成员域你这个测试成功,是因为你都在同一个机器(而且是同一个进程),因为你这个jvm已经把count加载进来了,所以你获取的是加载好的count,如果你是传到另一台机器或者你关掉程序重写写个程序读入test.obj,此时因为别的机器或新的进程是重新加载count的,所以count信息就是初始时的信息。====================

    二,ObjectInputStream和ObjectOutputStream类的了解:

      1. ObjectOutputStream构造方法:public ObjectOutputStream(OutputStream out)  throws IOException
      2. ObjectInputStream  特有方法:public final Object  readObject()  throws IOException,  ClassNotFoundException            从 ObjectInputStream 读取对象。
      3. ObjectOutputStream 特有方法:public final void writeObject (Object obj)  throws IOException 将指定的对象写入 ObjectOutputStream。

    三,序列化操作步骤:

      1. 被序列化对象实现Serializable接口
      2. 确定类中的serialVersionUID。=========序列化运行时使用一个称为 serialVersionUID的版本号与每个可序列化类相关联,用于验证序列化对象的发送者和接收者是否为同一对象。如果接收者加载的该对象的类的 serialVersionUID与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为"serialVersionUID"的字段(该字段必须是静态 (static)、最终 (final)的 long 型字段)显式声明其自己的serialVersionUID=========
      3. 创建对象写入流,与文件关联。           ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/obj.txt"));
      4. 通过写入writeObject(Object obj)方法,将对象作为参数传入,即可写入文件。oos.writeObject(obj);

    四,代码练习:

     

     1 import java.io.*;
     2 
     3 public class ObjectStreamDemo {
     4         public static void main(String[] args) {
     5             //声明并实例化被序列化对象
     6             Person per = new Person("lisi",23,01,"ss");
     7             
     8             //序列化对象
     9             try {
    10                 myObjectStream_Write(per);
    11             } catch (FileNotFoundException e) {
    12                 System.out.println("文件没有找到"+e.toString());
    13             } catch (IOException e) {
    14                 System.out.println("序列化发生错误!"+e.toString());
    15             }
    16             
    17             //接收读取的对象
    18             Person per2=null;
    19             
    20             //反序列化对象
    21             try {
    22                   per2 = (Person)myObjectStream_Reader();
    23             } catch (FileNotFoundException e) {
    24                  System.out.println("序列还文件不存在"+e.toString());
    25             } catch (ClassNotFoundException e) {
    26                 System.out.println("类文件没有找到"+e.toString());
    27             } catch (IOException e) {
    28                 System.out.println("读取发生错误"+e.toString());
    29             }
    30             
    31             System.out.println(per2);
    32         }
    33         
    34         
    35         //自定义序列化 方法,将对象序列化到硬盘上
    36         public static void myObjectStream_Write(Object obj) throws FileNotFoundException, IOException{
    37             
    38             //声明序列化输出流对像。并于文件相关联
    39             ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/obj.txt"));
    40             
    41             //将对象序列化到硬盘上
    42             oos.writeObject(obj);
    43             
    44             //关闭流
    45             oos.close();
    46         }
    47         
    48         
    49         //自定义读取序列化对象方法
    50         public static Object myObjectStream_Reader() throws FileNotFoundException, IOException, ClassNotFoundException{
    51             
    52             //声明序列化输入流,并于文件关联
    53             ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/obj.txt"));
    54             
    55             
    56             //读入被序列化的对象
    57             Object object = ois.readObject();
    58             
    59             //关闭流
    60             ois.close();
    61             
    62             return object;
    63             
    64         }
    65 }

     

    Person 类:

     1 import java.io.Serializable;
     2 
     3 
     4 //定义Person类实现Serializable接口,表明可以被序列化
     5 public class Person implements Serializable{
     6        
     7     //定义serialVersionUID 表明版本号
     8     private static final long serialVersionUID = 1L;
     9     
    10     //定义类成员
    11     private String name;
    12     private int age;
    13     
    14     //transient修饰符修饰的成员不可以被序列化
    15     transient int id;
    16     
    17     //静态成员不可以被序列化
    18     static String country="aa";
    19     
    20     
    21     //定义构造方法
    22     public Person(String name,int age,int id,String country){
    23         this.name=name;
    24         this.age=age;
    25         this.id=id;
    26         this.country=country;
    27     }
    28     
    29     @Override
    30     public String toString(){
    31         return "name:"+name+"---"+"age:"+age+"----"+"id:"+id+"----"+"country"+country;
    32     }
    33 
    34 }

    第二讲:IO流(管道流)

    一,管道流:PipedInputStream 和 PipedOutputStream  (输入输出可以直接进行连接,不用再借助数组或集合等容器进行临时存储。通过结合线程使用)

      1. public class PipedInputStream  extends InputStream      管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。
        1. 构造方法:public PipedInputStream()   创建尚未连接的 PipedInputStream。在使用前必须将其连接到 PipedOutputStream
        2. 构造方法:public PipedInputStream(int pipeSize)  创建一个尚未连接的 PipedInputStream,并对管道缓冲区使用指定的管道大小。在使用前必须将其连接到 PipedOutputStream
        3. 构造方法:public PipedInputStream(PipedOutputStream src,int pipeSize) throws IOException  创建一个 PipedInputStream,使其连接到管道输出流 src,并对管道缓冲区使用指定的管道大小。写入 src 的数据字节可用作此流的输入。
        4. 方法:public void connect(PipedOutputStream src) throws IOException    使此管道输入流连接到管道输出流 src。如果此对象已经连接到其他某个管道输出流,则抛出 IOException
      2. public class PipedOutputStreamextends OutputStream     可以将管道输出流连接到管道输入流来创建通信管道。管道输出流是管道的发送端。
        1. 构造方法:public PipedOutputStream()       创建尚未连接到管道输入流的管道输出流。必须在使用之前将管道输出流连接到管道输入流(既可由接收者连接,也可由发送者连接)。
        2. 构造方法:public PipedOutputStream(PipedInputStream snk) throws IOException    创建连接到指定管道输入流的管道输出流。写入此流的数据字节稍后将用作 snk 的输入。
        3. 方法:public void connect(PipedInputStream snk)  throws IOException    将此管道输出流连接到接收者。如果此对象已经连接到其他某个管道输入流,则抛出 IOException

    二,操作步骤:

      1. 先创建一个读和写的两个类,实现Runnable接口,因为是两个不同的线程,覆盖run方法。========注:线程的异常要在内部处理=========
      2. 创建两个管道流,并用connect()方法将两个流连接
      3. 将管道流绑定到线程。
      4. 创建线程并执行。

    三,代码练习:

     

      1 import java.io.*;
      2 
      3 //定义一个类,实现启动一个线程,次线程包括一个读的管道刘
      4 class Read implements Runnable{
      5     private PipedInputStream in;
      6     public Read(PipedInputStream in){
      7         this.in = in;
      8     }
      9     
     10     @Override
     11     
     12     //覆写方法
     13     public void run(){
     14         
     15            //接受输入数据
     16            byte buff[] = new byte[1024];
     17            
     18            
     19            //记录数据长度
     20            int len=0;
     21            
     22            
     23            //循环接受数据
     24            while(true){
     25                try{
     26                    
     27                    //尝试读取数据
     28                    len = in.read(buff);
     29                    
     30                    //判断是否结束
     31                    if("over".equals(new String(buff,0,len-2)))
     32                        break;
     33                    
     34                    //输出用户输入的内容
     35                    System.out.println("管道读取内容为:"+new String(buff,0,len)+len);
     36                }catch(IOException e){
     37                    System.out.println("读取异常"+e.toString());
     38                }
     39            }
     40            
     41            //给出运行完毕提示
     42            System.out.println("运行完毕");
     43     }
     44 }
     45 
     46 //定义一个类,实现启动一个线程,此线程包括一个写的管道流
     47 class Write implements Runnable{
     48     
     49     //声明管道流对象
     50     private PipedOutputStream out;
     51     
     52     //构造方法
     53     public Write(PipedOutputStream out){
     54         this.out = out;
     55     }
     56     
     57     @Override
     58     
     59     //覆写方法
     60     public void run(){
     61         
     62            //接受管道数据
     63            byte buff[] = new byte[1024];
     64            
     65            int len=0;
     66            
     67            
     68            //循环读取
     69            while(true){
     70                try{
     71                    len=System.in.read(buff);
     72                    
     73                    
     74                    //输出数据
     75                    out.write(buff, 0, len);
     76                    
     77                    //判断是否结束
     78                    if("over".equals(new String (buff,0,len-2)))
     79                        break;
     80                }catch(IOException e){
     81                    System.out.println("管道读取流发生异常"+e.toString());
     82                }
     83            }
     84            
     85            //给出结束提示
     86            System.out.println("运行完毕");
     87            
     88     }
     89 }
     90 public class PipedStreamDemo {
     91              public static void main(String[] args) {
     92                  
     93                         //创建 管道流对象作为参数
     94                         PipedInputStream pis = new PipedInputStream();
     95                         PipedOutputStream pos = null;
     96                         
     97                         //将管道流相连接
     98                         try {
     99                             pos = new PipedOutputStream(pis);
    100                         } catch (IOException e) {
    101                             // TODO Auto-generated catch block
    102                             e.printStackTrace();
    103                         }
    104                         
    105                         //创建线程
    106                         Thread t1 = new Thread(new Read(pis));
    107                         Thread t2 = new Thread(new Write(pos));
    108                         
    109                         
    110                         //启动线程
    111                         t1.start();
    112                         t2.start();
    113             }
    114 }

     

    第三讲:IO流(RandomAccessFile)

    一,RandomAccessFile 类的简单了解。

        1. 类的声明:public class RandomAccessFileextends Object  implements DataOutput, DataInput, Closeable  此类的实例支持对随机访问文件的读取和写入。
        2. 类的说明:
          1. 该类不算是IO体系中的子类,而是直接继承Object,但是它是IO包成员,因为它具备读写功能,内部封装了一个数组,且通过getFilePointer方法获取指针位置,来对数组的元素进行操作,同时可通过seek方法改变指针的位置。
          2. 可以完成读写的原理:内部封装了字节输入流和输出流。
        3. 构造方法:public RandomAccessFile(File file, String mode) throws FileNotFoundException    创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
        4. 构造方法:public RandomAccessFile(String name, String mode) throws FileNotFoundException   建从中读取和向其中写入(可选)的随机访问文件流 ====注:由构造方法可以看出该类只能操作文件。且操作文件包括模式=====
        5. 方法:public long length() throws IOException    按字节测量的此文件的长度。
        6. public void seek(long pos) throws IOException    设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。===注:可以向前和向后寻找====
        7. public int skipBytes(int n) throws IOException    尝试跳过输入的 n 个字节以丢弃跳过的字节。返回:跳过的实际字节数。===注:只可以往前跳不可以往后跳=====

    =====注:关于读写模式的说明:如果模式为只读r,则不会创建文件,会去读一个已存在的文件,若文件不存在,则会出现异常。如果模式为读写rw,且该对象的构造函数要操作的文件不存在,会自动创建;如果存在,则不会覆盖====

    二,RandomAccessFile类的特点:

        1. 同一个类既有读方法也有写方法。
        2. 只能操作文件。
        3. 可以实现对文件的随机读写。

    三,代码练习:

     1 package com.examp.ch18;
     2 //需求:使用RandomAccessFileDemo进行读写操作
     3 
     4 import java.io.*;
     5 public class RandomAccessFileDemo {
     6     
     7     public static void main(String[] args)throws IOException {
     8         
     9         //创建文件对象
    10         File file =new File("E:/test.txt");
    11 
    12         //写数据
    13         writeFile(file);
    14 
    15         //读数据
    16         readFile(file);
    17 
    18     }
    19 
    20     //读取指定文件中的数据
    21     public static void readFile(File file)throws IOException{
    22         
    23         
    24         //创建随机读写对象,指定文件打开方式为只读
    25         RandomAccessFile raf=new RandomAccessFile(file,"r");
    26         
    27         //设置指针位置
    28         raf.seek(8);
    29 
    30         //读取四个字节存入
    31         byte[] by=new byte[4];
    32         
    33         
    34         //读数据
    35         raf.read(by);
    36         
    37         
    38         //将存入数据的字节数组转换为字符串
    39         String name=new String(by);
    40         
    41         
    42         //读取年龄
    43         int age=raf.readInt();
    44         
    45         System.out.println("name="+name+"age="+age);
    46 
    47         //关闭流对象
    48         raf.close();
    49     }
    50 
    51     //创建方法将数据写入指定文件中
    52     public static void writeFile(File file)throws IOException{
    53         
    54         //创建对象,文件打开方式为读写
    55         RandomAccessFile raf=new RandomAccessFile(file,"rw");
    56         
    57         //写入姓名
    58         raf.write("张三".getBytes());
    59         
    60         
    61         //写入年龄,这里调用了写一个int方法
    62         raf.writeInt(23);
    63 
    64         raf.write("李四".getBytes());
    65         raf.writeInt(100);
    66       
    67         //改变指针位置,改变第一个对象的值
    68         raf.seek(8*0);
    69         raf.write("小三".getBytes());
    70         raf.writeInt(3);
    71 
    72         
    73         //改变指针位置
    74         raf.skipBytes(8*2);
    75         raf.write("王五".getBytes());
    76         raf.writeInt(5);
    77 
    78         //关闭流
    79         raf.close();    
    80     }
    81 }

     

    第四讲:IO流(操作基本数据类型的流对象DataStream)

    一,ByteArrayInputStream和ByteArrayOutputStream 类的简单了解:

        1. ByteArrayInputStream 在构造时,需要接受数据源。。而且数据源是一个字节数组。
        2. ByteArrayOutputStream 在构造时,不需要指定数据源,因为在其内部已经封装的可变长度的字节数组。
        3. 这两个流对象操作的都是数组,没有使用系统资源,所以不需要关闭。
        4. 基本思想:用流的思想操作数组。
        5. ByteArrayOutputStream  方法:public void writeTo(OutputStream out)  throws IOException         将此 byte 数组输出流的全部内容写入到指定的输出流参数中。==注:此方法抛出异常。===

    二,对应的字符操作类:CharArrayReader和CharArrayWriter

            对应的字符串操作类: StringReader和StringWriter

    三,代码练习:

     1 import java.io.*;
     2 
     3 public class ByteArrayInputStreamDemo {
     4            public static void main(String[] args) {
     5                
     6                //定义字节操作输入流,源为一个字符串的字节数组形式
     7                ByteArrayInputStream bais=new ByteArrayInputStream("abcdef".getBytes());
     8                
     9                //定义字节操作输出流
    10                ByteArrayOutputStream baos=new ByteArrayOutputStream();
    11                
    12                //接受读入的内容
    13                int by=0;
    14                
    15                //循环读取写入内容
    16                while((by = bais.read())!=-1){
    17                    baos.write(by);
    18                }
    19                
    20                //输出字节操作流写入的内容
    21                System.out.println(baos.toString());
    22         }
    23 }

    第五讲:IO流(ByteArrayStream)

     

     

    第六讲:IO流(转换流的字符编码)

    一,字符概述:

      1. Java IO 操作中可以加入字符编码表的四个对象:
        1. 转换流:InuputStreamReader和OutputStreamWriter
        2. 打印流:PrintStream和PrintWriter    =====注:只有输出流=====

    二,编码表的由来:计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表。

    1. 常见的编码表:ASCII:美国标准信息交换码表。用一个字节的7位表示
    2. IOS8859-1:拉丁码表;欧洲码表。用一个字节的8位表示。====注:打头为 1======
    3. GB2312:中国的中文编码表(早期)两个字节表示一个字符(6-7千字符)。====注:打头的是两个高位为1的两个字节编码。===
    4. GBK:中国的中文编码表升级,融合了更多的中文文字字符。(两万字符左右)。====注:打头的是两个高位为1的两个字节编码。===
    5. Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode。
    6. UTF-8:最多用三个字节表示一个字符的编码表,根据字符所占内存空间不同,分别用一个、两个、三个字节来编码。

      1. UTF-8编码格式:一个字节:0开头
      2.  两个字节:字节一  ---> 110    位数:10 ~ 6 。字节二  ---> 10     位数:5 ~ 0
      3. 三个字节:字节一  ---> 110    位数:15 ~ 12 字节二  ---> 10     位数:11 ~ 6 字节三 ---> 10     位数:5 ~ 0

    三,代码练习:

      1 import java.io.*;
      2 
      3 
      4 public class EncodingStream {
      5              public static void main(String[] args) {
      6                  
      7                  //分别创建两个文件对象,用来存储两种编码格式的数据
      8                  File file_GBK = new File("E:/gbk.txt");
      9                  File file_UTF = new File("E:/utf.txt");
     10                  
     11                  //分别按照两种编码格式写入数据
     12                  try {
     13                     writeText_GBK(file_GBK);
     14                     writeText_UTF(file_UTF);
     15                 } catch (IOException e) {
     16                     System.out.println("写入文件发生异常"+e.toString());
     17                 }
     18                  
     19                  
     20                  //按照两种编码格式分别读取两个文件
     21                  try {
     22                      
     23                      //正常
     24                      System.out.println("正常:");
     25                     readText_GBK(file_GBK);
     26                     //乱码
     27                     System.out.println("乱码");
     28                     readText_GBK(file_UTF);
     29                     //正常
     30                     System.out.println("正常:");
     31                     readText_UTF(file_UTF);
     32                     //乱码
     33                     System.out.println("乱码");
     34                     readText_UTF(file_GBK);
     35                 } catch (IOException e) {
     36                     System.out.println("读入文件发生错误"+e.toString());
     37                 }
     38                  
     39             }
     40              
     41              
     42              //定义方法将数据按GBK编码写入文件
     43              public static void writeText_GBK(File file) throws IOException{
     44                  
     45                     //创建输出字符流,使用指定的文件,以及编码
     46                     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"gbk");
     47                     
     48                     
     49                     //写入内容
     50                     osw.write("黑马训练营");
     51                     
     52                     //刷新流
     53                     osw.flush();
     54                     //关闭流
     55                     osw.close();
     56              }
     57              
     58              
     59              //定义方法,将数据按照GBK编码从文件中读入
     60              public static void readText_GBK(File file) throws IOException{
     61                  
     62                     //创建文件读取字符流,使用指定的编码,以及文件
     63                     InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"gbk");
     64                     
     65                     //接受读入的字符
     66                     char ch[] = new char[1024];
     67                     
     68                     //标记读入的字符数
     69                     int  len=0;
     70                     
     71                     //循环读取打印
     72                     while((len=isr.read(ch))!=-1){
     73                         System.out.println(new String(ch,0,len));
     74                     }
     75                     //关闭流操作
     76                     isr.close();
     77              }
     78              
     79              
     80              //定义方法,将数据按照UTF-8编码写入指定的文件
     81              public static void writeText_UTF(File file) throws IOException{
     82                  
     83                     //创建输出字符流,使用指定的文件,以及编码
     84                     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
     85                     
     86                     //写出数据
     87                     osw.write("黑马训练营");
     88                     
     89                     osw.flush();
     90                     
     91                     osw.close();
     92              }
     93              
     94              
     95              //定义方法,将数据按照UTF-8编码从指定文件读入
     96              public static void readText_UTF(File file)throws IOException{
     97                     //创建文件读取字符流,使用指定的编码,以及文件
     98                     InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"UTF-8");
     99                     
    100                     //定义数组接受字符
    101                     char ch[] = new char[1024];
    102                     
    103                     //标记
    104                     int len=0;
    105                     
    106                     //循环读取
    107                     while((len=isr.read(ch))!=-1){
    108                         System.out.println(new String(ch,0,len));
    109                     }
    110                     
    111                     isr.close();
    112              }
    113 }

    第七讲:字符编码

    一,编码和解码

      1. 编码:字符串变成字节数组       String  --->  byte[]  :srt.getBytes(charsetName)
      2. 解码:字节数组变成字符串         byte[]   --->  String :newString(byte[],charsetName)

    二,编码和解码的字符集转换注意事项

        1. 如果编码失败,解码就没意义了。
        2. 如果编码成功,解码出来的是乱码,,则需对乱码通过再次编码(用解错码的编码表),然后再通过正确的编码表解码。针对于IOS8859-1是通用的。
        3. 如果用的是GBK编码,UTF-8解码,此时通过再次编码后解码的方式,就不能成功了,因为UTF-8也支持中文,在UTF-8解的时候,会将对应的字节数改变,所以不会成功。

     

    三,代码练习:

     1 import java.util.Arrays;
     2 
     3 public class EncodingDemo {
     4             public static void main(String args[]) throws Exception{
     5                 
     6                 //创建一个字符串
     7                 String s="您好";
     8                 //获得字符串的GBK 码表
     9                 byte[] b1 = s.getBytes("gbk");
    10                 //输出码表
    11                 System.out.println(Arrays.toString(b1));
    12                 //重新编码
    13                 String s1 = new String(b1,"gbk");
    14                 
    15                 System.out.println("s1="+s1);
    16                 
    17                 //获取字符串的ISO8859-1码表
    18                 byte[] b2 = s1.getBytes("ISO8859-1");
    19                 //输出码表
    20                 System.out.println(Arrays.toString(b2));
    21                 //重新编码
    22                 String s2 = new String (b2,"gbk");
    23                 
    24                 System.out.println(s2);
    25             }
    26 }

    第八讲:字符编码-联通

    一,对于中文的”联通“,这两个字比较特别,它的二进制位正好是和在UTF-8中两个字节打头的相同,所以在文本文件中,如果单独写“联通”或者和满足UTF-8编码格式的字符一起保存时,记事本就会用UTF-8来进行解码动作,这样显示的就会是乱码。

        解决办法:在联通前面加上任意中文字符。

    二,代码练习:

     

     1 import java.io.UnsupportedEncodingException;
     2 
     3 public class LianTongDemo {
     4             public static void main(String[] args) throws UnsupportedEncodingException {
     5                    String s = "联通";
     6                    
     7                    byte[] bytes = s.getBytes("gbk");
     8                    
     9                    for(byte b : bytes){
    10                        System.out.println(Integer.toBinaryString(b&255));
    11                    }
    12             }
    13 }

     

    第九讲:练习

    一,需求分析:

                      有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括姓名,三门课成绩输入的格式:如:张三,30,40,60计算出总成绩,并把学生的信息和计算出的总分数由高低顺序存放在磁盘文件“stuinfo.txt”中

    二,思路:

      1. 描述对象
      2. 定义一个可操作学生对象的工具类。 
      3. 通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。
      4. 因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序。所以可以使用TreeSet。
      5. 将集合的信息写入到一个文件中。

    三,代码练习:

      1 import java.io.*;
      2 import java.util.*;
      3 
      4 
      5 //学生类实现Comparable接口
      6 class Student implements Comparable<Student>{
      7     private String name;
      8     private int sx,yy,yw,sum;
      9     Student(String name,int sx,int yw,int yy){
     10         this.name=name;
     11         this.sx=sx;
     12         this.yw=yw;
     13         this.yy=yy;
     14         sum=sx+yw+yw;
     15     }
     16 
     17     //获取总成绩
     18     public int getSum(){
     19         return sum;
     20     }
     21 
     22     //获取姓名
     23     public String getName()
     24     {
     25         return name;
     26     }
     27 
     28     //复写compareTo方法
     29     public int compareTo(Student s)    {
     30         
     31         int num=new Integer(this.sum).compareTo(new Integer(s.sum));
     32         if(num==0)
     33             return this.name.compareTo(s.name);
     34         return num;
     35     }
     36     
     37     //复写hashCode
     38     public int hashCode(){
     39         
     40         return name.hashCode()+sum*33;
     41     }
     42 
     43     //复写equals
     44     public boolean equals(Object obj){
     45         
     46         if(!(obj instanceof Student))
     47             throw new ClassCastException("类型不匹配");
     48         Student s=(Student)obj;
     49         return this.name.equals(s.name)&&this.sum==s.sum;
     50     }
     51 
     52     
     53     //复写toString
     54     public String toString(){
     55         return "Student["+name+","+sx+","+yw+","+yw+"]";
     56     }
     57 }
     58 
     59 //学生工具类
     60 class StudentTools{
     61     //从键盘读取学生信息方法,以学生自身排序方式存入集合中
     62     public static Set<Student> getStudentInfo_1()throws IOException
     63     {
     64          return getStudentInfo_2(null);
     65     }
     66 
     67     //从键盘读取学生信息方法,以比较器排序方式存入集合中
     68     public static Set<Student> getStudentInfo_2(Comparator<Student> cmp)throws IOException
     69     {
     70         //键盘录入
     71         BufferedReader bis=
     72             new BufferedReader(new InputStreamReader(System.in));
     73         String info=null;
     74 
     75         //定义一个集合,用来存储学生对象
     76         Set<Student> set=null;//---------
     77         if(cmp==null)
     78             set=new TreeSet<Student>();
     79         else
     80             set=new TreeSet<Student>(cmp);
     81 
     82         //读取数据
     83         while((info=bis.readLine())!=null)
     84         {
     85 
     86             if("over".equals(info)) 
     87                 break;
     88 
     89             String[] in=info.split(",");
     90             //将学生对象存入集合中
     91             set.add(new Student(in[0],Integer.parseInt(in[1]),
     92                                     Integer.parseInt(in[2]),
     93                                     Integer.parseInt(in[3])));
     94         }
     95         bis.close();//关流
     96 
     97         return set;
     98     }
     99 
    100     //把学生信息按照指定属性写入指定文件中
    101     public static void writeToFile(Set<Student> set,File file)throws IOException
    102     {
    103         //关联文件
    104         BufferedWriter bw=new BufferedWriter(new FileWriter(file));
    105 
    106         //遍历
    107         for (Student stu : set)
    108         {
    109             //将学生信息写入指定文件中
    110             bw.write(stu.toString()+"	");
    111             bw.write(stu.getSum()+"");
    112             bw.newLine(); 
    113             bw.flush();
    114         
    115         }
    116         
    117         bw.close();//关流
    118     }
    119 }
    120 
    121 
    122 public class  StudentInfoTest
    123 {
    124     public static void main(String[] args) 
    125     {
    126         //定义一个翻转自身比较性的比较器
    127         Comparator<Student> cmp=Collections.reverseOrder();
    128         try
    129         {
    130             //指定文件
    131             File file =new File("stdinfo.txt");
    132     
    133             //调用学生工具类的获取信息方法,将信息存入集合中
    134             Set<Student> set=StudentTools.getStudentInfo_2(cmp);
    135 
    136 
    137             //将学生信息写入指定文件中
    138             StudentTools.writeToFile(set,file);
    139         }
    140         catch (IOException e)
    141         {
    142             throw new RuntimeException("学生信息获取写入失败");
    143         }    
    144     }
    145 }
     
  • 相关阅读:
    修改注释的风格
    PHP in_array
    PHP end
    PHP each
    GitHub和SourceTree入门教程
    面试题解析(不定时更新)
    Container With Most Water
    Minimum Path Sum
    Generate Parentheses
    Unique Paths
  • 原文地址:https://www.cnblogs.com/xiaochongbojue/p/4052580.html
Copyright © 2011-2022 走看看