TwentyandTwenty-one-java 比较器与IO流

//TwentyDay

1、制定排序规则的第二种方法

使用比较器

//商品类

class product{
  int pno;
  public product(int pno){
      this.pno=pno;
  }

  @Override
  public String toString() {
      return "product{" +
              "pno=" + pno +
              '}';
  }
}

//商品比较器

//创建一个商品比较器 实现Comparator<T>接口 重写compare(T a,T b);方法
class productComparator implements Comparator<product> {

  @Override
  public int compare(product o1, product o2) {
      return o1.pno-o2.pno ;
  }
}

//检测商品比较器

public static void main(String[] args) {
  TreeSet<product> t=new TreeSet<>(new productComparator());
  product p1=new product(110);
  product p2=new product(123);
  product p3=new product(100);
  t.add(p1);
  t.add(p2);
  t.add(p3);
  for (product product : t) {
      System.out.println(product);
  }
}

//运行结果

product{pno=100}

product{pno=110}

product{pno=123}

//可以使用匿名内部类方式来写

TreeSet<product> t=new TreeSet<>(new Comparator<product>() {
  @Override
  public int compare(product o1, product o2) {
      return o1.pno-o2.pno;
  }
});

//什么时候用Comparable,Comparator?

比较规则不会发生改变的时候,或规则只有一个的时候建议使用Comparable接口,若比较规则多变则建议使用Comparator接口

2、Collections工具类

//student类

class student implements Comparable<student>{
  int sno;
  public student(int sno){
      this.sno=sno;
  }

  @Override
  public String toString() {
      return "student{" +
              "sno=" + sno +
              '}';
  }

  @Override
  public int compareTo(student o) {
      return this.sno-o.sno;
  }
}

//Collections工具类的常用方法

*Collections.synchronizedList()把非线程安全数组集合转换成线程安全的

*Collections.sort()给集合排序 只限List集合,Set集合要转换成List集合

public static void main(String[] args) {
  List<String> list=new ArrayList<>();
  //ArrayList不是线性安全的,变成线性安全的
  Collections.synchronizedList(list);
  //排序
  list.add("asd");
  list.add("abc");
  list.add("afz");
  Collections.sort(list);
  for (int i = 0; i < list.size(); i++) {
      System.out.println(list.get(i));
  }
  //对自定义类进行排序
  List<student> stu=new ArrayList<>();
  stu.add(new student(18010));
  stu.add(new student(18012));
  stu.add(new student(18002));
  //Collections只能对继承了Comparable接口的类进行排序
  Collections.sort(stu);
  for (student student : stu) {
      System.out.println(student);
  }
  //对set集合进行排序
  Set<String> set=new HashSet();
  set.add("our");
  set.add("come");
  set.add("on");
  //把set转换成List的类型 ,因为Collections工具类只能对List进行排序
  List<String> str=new ArrayList<>(set);
  Collections.sort(str);
  for (String s : str) {
      System.out.println(s);
  }
}

//运行结果

abc

afz

asd

student{sno=18002}

student{sno=18010}

student{sno=18012}

come

on

our

//Twebty-oneDay

1、流的简介

什么是IO流,什么是IO?

I:Input

o:Output

通过IO可以完成硬盘文件的读和写

IO流的分类?

一种方式是按照流的方向进行分类: 以内存作为参照物,往内存中去,叫做输入流(Input)又叫做读(Read) 从内存中出来,叫做输出流(Output)又叫做写(Write)

另一种方式是按照读取数据方式的不同进行分类 按照字节的读取数据方式,一次只读一个字节byte,等同于一次读取八 个二进制位,这种流是万能的,什么类型的文件都可以读取。 按照字符的方式读取数据,一次只读取一个字符,这种流是为了方便读 取普通文本存在的,只能读取纯文本文件,连word文档都不能读取。

总结流的分类:输入流,输出流,字节流,字符流

2、IO流

Java IO流的四大家族:它们都是抽象类

java.io.InputStream 字节输入流

java.io.OutputStream 字节输出流

java.io.Reader 字符输入流

java.io.Writer 字符输出流

注意:凡是类名以“Stream”结尾的都是字节流,凡是以“Reader/Writer”结 尾的都是字符流

所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有close() 方法。用完流管道后一定要关闭,不然占用资源。

所有的输出流都实现了:java.io.Flushable接口,都是可刷新的,都flush() 方法,在输入流最终输出之后,一定要记得flush刷新一下,这个刷新表示 将通道/管道当中剩余未输出的数据强行输出完(清空管道!)没有flush的 话可能会导致数据丢失。

java.io包下需要掌握的16个流:

文件专属流:

java.io.FileInputStream

java.io.FileOutputStream

java.io.FileReader

java.io.FileWriter

转换流:(将字节流转换成字符流)

java.io.InputStreamReader

java.io.OutputStreamWriter

缓冲流专属:

java.io.BufferedReader

java.io.BufferedWriter

java.io.BufferedInputStream

java.io.BufferedOutputStream

数据流专属:

java.io.DataInputStream

java.io.DataOutputStream

标准输出流:

java.io.PrintWriter

java.io.PrintStream

对象专属流:

java.io.ObjectInputStream

java.io.ObjectOutputStream

3、FileInputStream

1>、read()读

public static void main(String[] args) {
  // 创建文件字节输入流对象
  FileInputStream file=null;
  try {
      file=new FileInputStream("D:\\word文档\\js.txt");
      //读
      /*
      int readdata = file.read();//读到返回字节本身,读不到返回-1
      System.out.println(readdata);//我在文档中放了a ,读取出来的是97
      一次只读一个字节 这样内存与硬盘交互太过于频繁。浪费时间,不用!
        */
      int readdata=0;
      while((readdata=file.read())!=-1){
          System.out.print(readdata+" ");
      }

  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  } finally {
      //判断是否为空的快捷键是ifn
      if (file != null) {
          try {
              file.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

2>、上面的方法太笨重,采用byte数组来读数据 read(byte[] b)

public static void main(String[] args) {
  FileInputStream file=null;
  try {
      //相对路径?相对路径一定是从当前所在位置作为起点开始找
      //IDEA默认的当前路径是工程Project的根。
      file=new FileInputStream("java基础语法/src/TwentyOneDay/tempfile04");
      byte[] b=new byte[4];
      int bCounts = file.read(b);//读取后的返回值是读取到元素的个数
      //若读到空,返回-1
      System.out.println(bCounts);//我在文件中写的是“abcdef” 数组每次最多读b.lenght个字节,故返回值是4
      //把读到的byte数组转换为字符串输出 转换从数组0下标开始到每次读到数据个数结束 如这一次读了4个,则转换[0,3]的元素
      System.out.println(new String(b,0,bCounts));
      /*
      new String(b,0,bCounts)这样转换的原因是:第二次取两个元素ef,但是数组中存储的是efcd(ef把原先的ab覆盖了),若是不限制转换范围
      则第二次取出的就是efcd了
        */
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  } finally{
      if (file == null) {
          try {
              file.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

整理:

public static void main(String[] args) {
  FileInputStream file=null;
  try {
      file = new FileInputStream("java基础语法/src/TwentyOneDay/tempfile04");
      //使用byte数据读数据
      byte[] bytes=new byte[4];
      int readCount =0;
      while((readCount = file.read(bytes))!=-1){
          System.out.print(new String(bytes,0,readCount));//abcdef
      }

  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  } finally{
      if (file != null) {
          try {
              file.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

3>FileInputStream的其他方法

int available() //返回剩余未读的字节个数

long skip(long n) //丢弃输入流的n节数据

public static void main(String[] args) {
  FileInputStream file=null;
  try {
        file=new FileInputStream("java基础语法/tempfile02");
        //读取文件数据字节总量
      int Count = file.available();
      System.out.println("字节数总量:"+Count);//字节数总量:7
      //知道字节数总量就可以作为byte数组的长度,一次性把数据读完,不需要循环
      //这种方式不适用大文件,因为byte数组不能太大
      byte[] b=new byte[Count];
      //读(用数组装数据)
      file.read(b);
      System.out.println(new String(b));//abcdefg
      //skip() 跳过字节
      file.skip(2);
      int data = file.read();
      System.out.println(data);//99 跳过了ab 取c 99
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  } finally {
      if (file != null) {
          try {
              file.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

4、FileOutputStream

public static void main(String[] args){
  FileOutputStream file=null;
  FileOutputStream file1=null;
  try {
      //创建方式一
      //Myfile文件不存在,它会自动创建在Project根下,但是它会清空文件里原来的内容后在写入现在的数据
      file=new FileOutputStream("Myfile");
      byte[] b={45,56,98,99};
      file.write(b);//文件中显示:-8bc
      //创建方式二
      //第二个参数是是否追加,true为在文件内容后追加,false为重写文件内容
      file1=new FileOutputStream("Myfile",true);
      file1.write(b);//文件中显示:-8bc-8bc
      file1.write(b,0,2);//-8bc-8bc-8
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  } finally{
      if (file != null) {
          try {
              file.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

5、文件的拷贝

public static void main(String[] args) {
  FileInputStream fis=null;
  FileOutputStream fos=null;
  try {
      //输入流
        fis=new FileInputStream("D:/word文档/js.txt");
        //输出流
      fos=new FileOutputStream("D:/ppt文档/jsCopy.txt");
      //使用byte数组
      byte[] b=new byte[1024*1024];//1M
      //边读边写
      int readdata=0;
      while((readdata=fis.read(b))!=-1){
          fos.write(b);
      }

  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  } finally{
      /*
      两个文件的关闭最好使用两个try,原因是其中一个出错另一个也可以照常关闭
        */
      if (fis != null) {
          try {
              fis.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      if (fos != null) {
          try {
              fos.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
}

5、BufferedReader

BufferedReader: 带有缓冲区的字符输入流 使用这个流的时候不需要自定义char数组或者byte数组。自带缓冲区

public static void main(String[] args) {
  BufferedReader reader=null;
  try {
      //BufferedReader的参数是流,故需要创建一个Reader类型的流
      FileReader fr=new FileReader("java基础语法/src/TwentyOneDay/copyTest01.java");
      //当一个流的构造方法需要传一个流的时候,被传进去的流叫做【节点流】
      //外部负责包装的这个流叫做【包装流/处理流】
      //对于当前来说 fr就是一个节点流,reader就是一个包装流
        reader=new BufferedReader(fr);
      //读取文本行
      String s=null;
      while((s=reader.readLine())!=null){
          System.out.println(s);
      }
  } catch (FileNotFoundException e) {
      e.printStackTrace();
  } catch (IOException e) {
      e.printStackTrace();
  }finally {
      //关闭流
      if (reader!= null) {
          try {
              //对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭
              reader.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }

}

6、转换流

帮助字节流转换成字符流 可以传给缓冲流

public static void main(String[] args) throws Exception{
  //这是一个字节流
  FileInputStream is=new FileInputStream("java基础语法/src/TwentyOneDay/copyTest01.java");
  //转换流 需要传一个字节流转换成字符流
  InputStreamReader reader = new InputStreamReader(is);
  //需要传一个字符流(Reader类型的)
  BufferedReader br=new BufferedReader(reader);
  //读数据
  String s=null;
  while((s=br.readLine())!=null){
      System.out.println(s);
  }
  //关闭最外层流
  br.close();
  //合并
  BufferedReader br1=new BufferedReader(new InputStreamReader(new FileInputStream("tempfile02")));
  //关闭
  br1.close();
}

7、OutputStreamWriter转换流

 public static void main(String[] args) throws Exception {
//       BufferedWriter bw=new BufferedWriter(new FileWriter("Myfile"));
      BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Myfile",true)));
      //写数据
      bw.write("hello world");
      bw.write("\n");
      bw.write("hello kitty");
      //关闭最外层流
      bw.close();
  }

8、标准输出流

public static void main(String[] args)throws Exception {
  //拆分
  PrintStream ps=System.out;
  ps.println("123");
  //合并
  System.out.println("234");
  //回顾System
  /*
  System.gc();
  System.exit(0);
  System.arraycopy();
  System.currentTimeMillis();
    */
  //标准输出流不在指向控制台,指向“Myfile”文件
  PrintStream printStream=new PrintStream(new FileOutputStream("myfile"));
  //修改输出方向,存储在“Myfile”文件中
  System.setOut(printStream);
  System.out.println("hello body!");

}

 

posted @ 2021-07-14 09:18  别不开心,过得去  阅读(68)  评论(0)    收藏  举报