除了重写compareTo方法比较TreeSet元素之外,还可以用比较器方式;
比较器实现java.util.comparator接口(Comparable是java.lang包下的,比较器是java.util包下的);
//转线程安全方法synchronizedList
//线程非安全
List ls = new ArrayList<>();
//转线程安全
Collections.synchronizedList(ls);
//sort方法
//对List中的元素进行排序,必须确保List中的元素实现了Comparable接口
List ls2 = new ArrayList();
ls2.add(new LoveMovie(2007));
ls2.add(new LoveMovie(1987));
ls2.add(new LoveMovie(2119));
Collections.sort(ls2);
for (LoveMovie loveMovie : ls2) {
System.out.println(loveMovie);
}
class LoveMovie implements Comparable {
int year;
public LoveMovie(int year) {
this.year = year;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "lm年份:" + this.year;
}
@Override
public int compareTo(LoveMovie o) {
// TODO Auto-generated method stub
return this.year - o.year;
}
}
//将HashSet转成List实现对hashSet的排序
HashSet hs = new HashSet<>();
hs.add("a3");
hs.add("a33");
hs.add("a2");
hs.add("aff");
for (String string : hs) {
System.out.println("hashset" + string);
}
List ls3 = new ArrayList<>(hs);
Collections.sort(ls3);
for (String string : ls3) {
System.out.println("List" + string);
}
I:input;O:output;
IO流的分类:
①按照流的方向进行分类:
输入流--往内存中去叫做输入,或者叫读(从硬盘读数据到内存);
输出流--从内存出去叫输出,或者叫写(从内存写数据到硬盘);
②按照数据的读取方式分类:
字节流--按照字节的方式读取数据,一次读取一个字节byte,等同于一次读取8个二进制位;这种流是万能的,可以读取任何类型的数据,包括文本、图片、声音文件、视频文件;
字符流--按照字符的方式读取,一次读一个字符;这种流是为了方便读取普通文本而存在的,这种流不能读取图片、声音文件、视频文件等;只能读取普通文本文件(能用记事本编辑的都是普通文本文件);
'a'在java中占两个字节,在windows操作系统中占一个字节;
流的四大家族:
java.io.InputStream---字节输入流
java.io.OutputStream---字节输出流
java.io.Reader---字符输入流
java.io.Writer---字符输出流
四大家族的首类都是抽象类,所有流都实现Closeble接口,都有close方法,都是可关闭的;
java的类中以Stream结尾的都是字节流,以Reader或者Writer结尾的都是字符流;
流是一个管道,是硬盘与内存直接的通道,用完一定要关闭,不然会占用很多资源;
所有输出流都继承了Flushable接口,都是可刷新的,都有flush方法;
输出流在最终输出之后一定要记得flush刷新一下,这个刷新表示将管道/通道中的残余数据强行输出完,刷新的作用就是清空管道,如果没有flush可能会导致数据丢失;
java.io包下重要的16个流:
文件专属:
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.FileReader;
java.io.FileWriter;
转换流(将字节流转换成字符流):
java.io.InputStreamReader;
java.io.OutputStreamReader;
缓冲流专属:
java.io.BufferInputStream;
java.io.BufferOuputStream;
java.io.BufferReader;
java.io.BufferWriter;
数据流专属:
java.io.DataInputStream;
java.io.DataOutputStream;
标准输出流:
java.io.PrintStream;
java.io.PrintWriter;
对象专属流:
java.io.ObjectInputStream;
java.io.ObjectOutputStream;
文件字节输入流,任何文件都可以用这个类读取,是万能的;
public static void test5() {
FileInputStream fis = null;
try {
fis = new FileInputStream("src/Movie/ab.txt");
byte[] b = new byte[4];
int n = 0;
while ((n = fis.read(b)) != -1) {
System.out.print(new String(b, 0, n));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 避免空指针异常
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
available方法:获取剩余的(没读到的)字节数;
//这种方式不太适合太大的文件,因为byte数组不能太大;
fis = new FileInputStream("src/Movie/aa.jpg");
byte[] b = new byte[fis.available()];
int t = fis.read(b);
System.out.println(t);
skip方法:跳过几个字节
fis = new FileInputStream("src/Movie/ab.txt");
fis.skip(3);
int t = fis.available();
System.out.println(t);
public static void test8() {
String pathFrom = "D:\\迅雷下载\\一路向北\\视频\\1 (31).mp4";
String pathTo = "C:\\Users\\Administrator\\Desktop\\临时\\abc.mp4";
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(pathFrom);
fos = new FileOutputStream(pathTo);
byte[] b = new byte[1024 * 1024];
int readCount = 0;
while ((readCount = fis.read(b)) != -1) {
fos.write(b, 0, readCount);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 分开try...catch,一起try可能导致另一个管道没有关闭
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void test10() {
FileWriter fw = null;
try {
fw = new FileWriter("C:\\Users\\Administrator\\Desktop\\临时\\abc.txt", true);
char[] c = { '春', '水', '碧', '于', '天' };
fw.write(c, 2, 3);
fw.write("画船听雨眠");
fw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void test9() {
FileReader fr = null;
try {
fr = new FileReader("C:\\Users\\Administrator\\Desktop\\临时\\bb.txt");
char[] c = new char[4];
int count = 0;
while ((count = fr.read(c)) != -1) {
System.out.print(new String(c, 0, count));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
拷贝文件
public static void test11() {
FileReader reader = null;
FileWriter writer = null;
try {
reader = new FileReader("C:\\Users\\Administrator\\Desktop\\炉石传说对决卡组\\脚本.txt");
writer = new FileWriter("C:\\Users\\Administrator\\Desktop\\炉石传说对决卡组\\脚本222.txt");
char[] chs = new char[1024 * 512];
int count = 0;
while ((count = reader.read(chs)) != -1) {
writer.write(new String(chs, 0, count));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
带有缓冲区的字符输入流
使用这个流的时候不需要自定义byte数组或者char数组,自带缓冲;
FileReader reader = new FileReader("aaa.txt");
BufferedReader br = new BufferedReader(reader);
当一个流的构造方法中需要另一个流的时候,这个被传进来的流被称为节点流;
外部负责包装的流称为包装流,还有一个名字叫做处理流;
上面的例子中,FileReader就是节点流,BufferedReader就是包装流;
对于包装流来说,只需要关闭最外层流就行,因为包装流实际关闭的是节点流;
public static void test12() throws Exception {
FileReader reader = new FileReader("C:\\Users\\Administrator\\Desktop\\炉石传说对决卡组\\脚本222.txt");
BufferedReader br = new BufferedReader(reader);
String str = null;
//readline方法读取一行,不带换行符
while ((str = br.readLine()) != null) {
System.out.print(str);
}
br.close();
}
InputStreamReader
public static void test13() throws Exception {
// FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\炉石传说对决卡组\\脚本222.txt");
// // 此处,InputStreamReader是包装流,FileInputStream是节点流
// InputStreamReader isr = new InputStreamReader(fis);
// // 此处,BufferedReader是包装流,InputStreamReader是节点流
// BufferedReader br = new BufferedReader(isr);
//合并
String str = null;
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\Users\\Administrator\\Desktop\\炉石传说对决卡组\\脚本222.txt")));
while ((str = br.readLine()) != null) {
System.out.println(str);
}
br.close();
}
OutputStreamWriter
public static void test14() throws Exception {
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("C:\\Users\\Administrator\\Desktop\\炉石传说对决卡组\\accc.txt", true)));
bw.write("春江潮水连海平");
bw.write("\n");
bw.write("海上明月共潮生");
bw.flush();
bw.close();
}
DataOutputStream:数据专属流,可以将数据与数据类型一并写入文件,用记事本打不开,不是普通的文本文件;
DataOutputStream dos = new DataOutputStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\临时\\aa"));
short a = 33;
int b = 123;
Long c = 34L;
float d = 3.14F;
double e = 3.15;
boolean f = false;
byte g = 1;
char h = 'a';
dos.writeShort(a);
dos.writeInt(b);
dos.writeLong(c);
dos.writeFloat(d);
dos.writeDouble(e);
dos.writeBoolean(f);
dos.writeByte(g);
dos.writeChar(h);
dos.flush();
dos.close();
DataIntputStream:数据字节输入流,DataOutputStream写入的数据,只能通过DataIntputStream读出来,并且读出的顺序要和写入的顺序一致,才能正常取出数据;
PrintStream:标准的字节输出流,默认输出到控制台,不需要手动close()关闭;
// 联合写
System.out.println("寒战");
// 分开写
PrintStream ps = System.out;
ps.println("DDDD");
ps.println("天下无贼");
改变标准输出流的输出方向,此为日志框架的实现原理
PrintStream out = new PrintStream(new FileOutputStream("C:\\Users\\Administrator\\Desktop\\临时\\log", true));
System.setOut(out);
System.out.println("黄梅时节家家雨");
System.out.println("青草池塘处处蛙");
//改变输出方向到控制台
PrintStream ps2 = System.out;
System.setOut(ps2);
System.out.println("有约不来过夜半");
System.out.println("闲敲棋子落灯花");
file是文件和目录路径名的抽象表示形式;
File类和四大家族没有任何关系,所以File不能完成文件的读和写;
一个File对象有可能是文件也可能是目录;
File相关方法:
File f = new File("C:\\Users\\Administrator\\Desktop\\临时");
System.out.println(f.getAbsolutePath());
if (f.exists()) {
// 判断文件或目录是否存在
// System.out.println(f.exists());
// 以文件的形式新建
// f.createNewFile();
// 以目录的形式新建
// f.mkdir();
// 创建多重目录
// f.mkdirs();
// 获取父文件的路径
// System.out.println(f.getParent());
// 获取文件的绝对路径
// File parentFile = f.getParentFile();
// System.out.println(parentFile.getAbsolutePath());
// 获取文件名
// System.out.println(f.getName());
// // 判断是否目录
// System.out.println(f.isDirectory());
// // 判断是否文件
// System.out.println(f.isFile());
// // 获取文件的最后修改时间,返回毫秒级时间戳
// Long lTime = f.lastModified();
// Date dt = new Date(lTime);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
// System.out.println(sdf.format(dt));
// // 获取文件大小
// System.out.println(f.length());
// 获取文件目录下的所有子文件
// File[] fs = f.listFiles();
// for (File file : fs) {
// System.out.println(file.getName());
// }
}
目录拷贝
public static void test19() {
String path = "D:\\个人资料";
String toPath = "E:\\copyDir\\ccc\\ddd";
File f = new File(toPath);
if (!f.exists()) {
f.mkdirs();
}
copyFile(path, toPath);
}
public static void copyFile(String path, String toPath) {
File f = new File(path);
File[] fs = f.listFiles();
for (File file : fs) {
System.out.println(file.getName());
String currentSourceFilePath = file.getAbsolutePath();
String currentToPath = toPath + "\\" + file.getName();
if (file.isDirectory()) {
File file2 = new File(currentToPath);
if (!file2.exists()) {
file2.mkdir();
}
copyFile(currentSourceFilePath, currentToPath);
} else {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(currentSourceFilePath);
fos = new FileOutputStream(currentToPath);
byte[] b = new byte[1024 * 1024];
int count = 0;
while ((count = fis.read(b)) != -1) {
fos.write(b, 0, count);
}
fos.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}