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!");
}
浙公网安备 33010602011771号