一、IO框架学习
 
1.流的概念
内存与存储设备之间传输数据的通道

2.流的分类
按方向【重点】
- 输入流:将<存储设备>中的内容读到<内存>中
 
- 输出流:将<内存>中的内容写到<存储设备>中
 
按单位
- 字节流:以字节为单位,可以读写所有数据
 
- 字符流:以字符为单位,只能读写文本数据
 
按功能
- 节点流:具有实际传输数据的读写功能
 
- 过滤流:在节点流的基础之上增强功能
 
3.字节流
字节流的父类(抽象类)
1 2 3 4 5 6 7 8 9
   |  public int read(){} public int read(byte[] b){} public int read(byte[] b, int off, int len){}
 
  public void write(int n){} public void write(byte[] b){} public void write(byte[] b, int off, int len){}
 
  | 
 
文件字节流
文件输入流


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | package IO.byteStream;
  import com.sun.org.apache.bcel.internal.generic.NEW;
  import java.io.FileInputStream; import java.io.IOException;
 
 
  public class Demo01 {     public static void main(String[] args) throws IOException {                  FileInputStream fileInputStream = new FileInputStream("e://a.txt");                                                                                          
          
 
 
 
 
 
 
 
          int count=0;         byte[] buff = new byte[4];         while ((count=fileInputStream.read(buff))!=-1){             System.out.println(new String(buff,0,count));         }         fileInputStream.close();     } }
 
  | 
 

拓展:new String()
1
   | new String(byte bytes[], int offset, int length) 
 
  | 
 


文件输出流


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | package IO.byteStream;
  import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets;
  public class Demo02 {     public static void main(String[] args) throws IOException {                  FileOutputStream fileOutputStream = new FileOutputStream("e://b.txt",true);                   fileOutputStream.write(97);         fileOutputStream.write('c');         fileOutputStream.write('c');         fileOutputStream.write('\n');                  String str = new String("helloworld");         fileOutputStream.write(str.getBytes(StandardCharsets.UTF_8));
          fileOutputStream.close();         System.out.println("执行完毕!");     } }
 
  | 
 

图片复制案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | package IO.byteStream;
  import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;
  public class Demo03 {     public static void main(String[] args) throws IOException {                           FileInputStream fileInputStream = new FileInputStream("e://a.jpg");                  FileOutputStream fileOutputStream = new FileOutputStream("e://b.jpg");                  byte[] bytes = new byte[1024];         int count=0;         while ((count=fileInputStream.read(bytes))!=-1){             fileOutputStream.write(bytes,0,count);         }                  fileOutputStream.close();         fileInputStream.close();         System.out.println("执行完毕!");     } }
 
  | 
 

字节缓冲流
缓冲流:BufferedInputStream/ BufferedOutputStream
- 提高IO效率,减少访问磁盘次数
 
- 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close
 


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | package IO.BufferedStream;
  import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException;
  public class Demo01 {          public static void main(String[] args) throws IOException {                  FileInputStream fileInputStream = new FileInputStream("e://a.txt");         BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);                  
 
 
 
 
 
                   byte[] bytes = new byte[1024];         int count = 0;         while ((count=fileInputStream.read(bytes))!=-1){             System.out.println(new String(bytes,0,count));         }                  bufferedInputStream.close();         fileInputStream.close();     } }
 
  | 
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | package IO.BufferedStream;
  import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets;
  public class Demo02 {          public static void main(String[] args) throws IOException {         FileOutputStream fileOutputStream = new FileOutputStream("e://c.txt",false);                  BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);         String str = new String("helloworld");                  bufferedOutputStream.write(str.getBytes(StandardCharsets.UTF_8));         bufferedOutputStream.flush();                  bufferedOutputStream.close();         System.out.println("进程完成");     } }
 
  | 
 

4.对象流
1
   | ObjectOutputStream / ObjectInputStream
 
  | 
 
- 增强了缓冲区功能
 
- 增强了读写8种基本数据类型和字符串的功能
 
- 增强了读写对象的功能
readObject() 从流中读取一个对象 
writeObject(Object obj) 向流中写入一个对象 
 
使用流传输对象的过程称为序列化、反序列化
ObjectOutputStream

ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。
只有支持java.io.Serializable接口的对象才能写入流中。  每个可序列化对象的类被编码,包括类的类名和签名,对象的字段和数组的值以及从初始对象引用的任何其他对象的关闭。 
方法writeObject用于将一个对象写入流中。  任何对象,包括字符串和数组,都是用writeObject编写的。 多个对象或原语可以写入流。  必须从对应的ObjectInputstream读取对象,其类型和写入次序相同。 
序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | package IO.objectStream;
  import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream;
  public class Demo01 {     public static void main(String[] args) throws IOException {                  FileOutputStream fileOutputStream = new FileOutputStream("e://stu.bin");                  ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);                  Student stu01 = new Student("张三", 18);         Student stu02 = new Student("李四", 18);         objectOutputStream.writeObject(stu01);         objectOutputStream.writeObject(stu02);                  objectOutputStream.flush();                  objectOutputStream.close();         System.out.println("序列化完毕!");     } }
 
  | 
 

1 2 3
   |  public interface Serializable { }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   |  package IO.objectStream;
  import java.io.Serializable;
  public class Student implements Serializable {     private String name;     private  int age;
      public Student() {     }
      public Student(String name, int age) {         this.name = name;         this.age = age;     }
      public String getName() {         return name;     }
      public void setName(String name) {         this.name = name;     }
      public int getAge() {         return age;     }
      public void setAge(int age) {         this.age = age;     }
      @Override     public String toString() {         return "Student{" +                 "name='" + name + '\'' +                 ", age=" + age +                 '}';     } }
 
  | 
 


ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象。
ObjectOutputStream和ObjectInputStream可以分别为与FileOutputStream和FileInputStream一起使用的对象图提供持久性存储的应用程序。  ObjectInputStream用于恢复先前序列化的对象。  其他用途包括使用套接字流在主机之间传递对象,或者在远程通信系统中进行封送和解组参数和参数。 
ObjectInputStream确保从流中创建的图中的所有对象的类型与Java虚拟机中存在的类匹配。  根据需要使用标准机制加载类。 
只能从流中读取支持java.io.Serializable或java.io.Externalizable接口的对象。 
反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | package IO.objectStream;
  import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream;
  public class Demo02 {          public static void main(String[] args) throws IOException, ClassNotFoundException {                  FileInputStream fileInputStream = new FileInputStream("e://stu.bin");                  ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);                  Student student01 = (Student) objectInputStream.readObject();         Student student02 = (Student) objectInputStream.readObject();                  objectInputStream.close();         System.out.println("执行完毕!");                  System.out.println(student01.toString());         System.out.println(student02.toString());     } }
 
  | 
 
Serializable 接口
类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。 可序列化类的所有子类型都是可序列化的。 序列化接口没有方法或字段,仅用于标识可串行化的语义。
注意事项
- 某个类要想序列化必须实现 
Serializable接口 
- 序列化类中对象属性要求实现 
Serializable接口 
- 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
 
- 使用transient修饰属性,这个属性就不能序列化
 
- 静态属性不能序列化
 
- 序列化多个对象,可以借助集合来实现
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | package IO.objectStream;
  import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList;
  public class Demo03 {     public static void main(String[] args) throws IOException {         FileOutputStream fileOutputStream = new FileOutputStream("e://bai.txt");         ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);         Student student = new Student("王麻子", 56);         Student student1 = new Student("王二", 96);         ArrayList<Student> students = new ArrayList<>();         students.add(student);         students.add(student1);         objectOutputStream.writeObject(students);         objectOutputStream.close();     } }
 
  | 
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | package IO.objectStream;
  import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.util.ArrayList;
  public class Demo04 {     public static void main(String[] args) throws IOException, ClassNotFoundException {         FileInputStream fileInputStream = new FileInputStream("e://bai.txt");         ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);         ArrayList arrayList = (ArrayList) objectInputStream.readObject();         System.out.println(arrayList);         objectInputStream.close();     } }
 
  | 
 

5.编码方式
常见编码
ASCII 码
- 学过计算机的人都知道 ASCII 码,总共有 128 个,用一个字节的低 7 位表示,0
31 是控制字符如换行回车删除等;32126 是打印字符,可以通过键盘输入并且能够显示出来。 
 
 
GBK(扩展GB2312)
- 全称叫《汉字内码扩展规范》,是国家技术监督局为 windows95 所制定的新的汉字内码规范,它的出现是为了扩展 GB2312,加入更多的汉字,它的编码范围是 8140~FEFE(去掉 XX7F)总共有 23940 个码位,它能表示 21003 个汉字,它的编码是和 GB2312 兼容的,也就是说用 GB2312 编码的汉字可以用 GBK 来解码,并且不会有乱码。
 
  
 
GB18030(兼容GB2312)
- 全称是《信息交换用汉字编码字符集》,是我国的强制标准,它可能是单字节、双字节或者四字节编码,它的编码与 GB2312 编码兼容,这个虽然是国家标准,但是实际应用系统中使用的并不广泛。
 
  
 
Unicode编码集
- UTF-8
- UTF-16 统一采用两个字节表示一个字符,虽然在表示上非常简单方便,但是也有其缺点,有很大一部分字符用一个字节就可以表示的现在要两个字节表示,存储空间放大了一倍,在现在的网络带宽还非常有限的今天,这样会增大网络传输的流量,而且也没必要。而 UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符可以是由 1~6 个字节组成。
 
- UTF-8 有以下编码规则:
- 如果一个字节,最高位(第 8 位)为 0,表示这是一个 ASCII 字符(00 - 7F)。可见,所有 ASCII 编码已经是 UTF-8 了。
 
- 如果一个字节,以 11 开头,连续的 1 的个数暗示这个字符的字节数,例如:110xxxxx 代表它是双字节 UTF-8 字符的首字节。
 
- 如果一个字节,以 10 开始,表示它不是首字节,需要向前查找才能得到当前字符的首字节
 
 
 
 
Reader类
Reader 类是 Java 的 I/O 中读字符的父类,而 InputStream 类是读字节的父类,InputStreamReader 类就是关联字节到字符的桥梁,它负责在 I/O 过程中处理读取字节到字符的转换,而具体字节到字符的解码实现它由 StreamDecoder 去实现,在 StreamDecoder 解码过程中必须由用户指定 Charset 编码格式。值得注意的是如果你没有指定 Charset,将使用本地环境中的默认字符集,例如在中文环境中将使用 GBK 编码。

Writer类
字符的父类是 Writer,字节的父类是 OutputStream,通过 OutputStreamWriter 转换字符到字节。如下图所示:

6.字符流
问题引入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | package IO.charStream;
  import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;
  public class Demo01 {     public static void main(String[] args) throws IOException {         FileInputStream fileInputStream = new FileInputStream("e://baixiao.txt");
          int data=0;         while ((data=fileInputStream.read())!=-1){             System.out.print((char)data);           }
          fileInputStream.close();     } }
 
  | 
 

字符流的父类(抽象类)
reader 字符输入流
public int read(){} 
public int read(char[] c){} 
public int read(char[] b, int off, int len){} 
Writer 字符输出流
public void write(int n){} 
public void write(String str){} 
public void write(char[] c){} 
FileReader

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | package IO.charStream;
  import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException;
  public class Demo02 {     public static void main(String[] args) throws IOException {                  FileReader fileReader = new FileReader("e://baixiao.txt");                  
 
 
 
 
 
                   char[] chars = new char[2];         int data=0;         while ((data=fileReader.read(chars))!=-1){             System.out.println(new String(chars, 0, data));         }                  fileReader.close();     } }
 
  | 
 

FileWriter

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | package IO.charStream;
  import java.io.FileWriter; import java.io.IOException;
  public class Demo03 {     public static void main(String[] args) throws IOException {         FileWriter fileWriter = new FileWriter("e://hahah.txt");         String str="Java是世界上最好的语言!";         for (int i=0;i<5;i++) {             fileWriter.write(str);         }         fileWriter.close();         System.out.println("执行完毕!");     } }
 
  | 
 

进行文本文件复制
不能复制图片或二进制文件(声音图片),但是使用字节流可以复制任意文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | package IO.charStream;
  import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;
  public class Demo04 {     public static void main(String[] args) throws IOException {                  FileReader fileReader = new FileReader("e://hahah.txt");         FileWriter fileWriter = new FileWriter("e://hahah2.txt");                  int data=0;         while ((data=fileReader.read())!=-1){             fileWriter.write(data);             fileWriter.flush();         }                  fileReader.close();         fileWriter.close();         System.out.println("读写完成");     } }
 
  | 
 

字符流不能读取图片原因分析:
二进制文件没有字符编码,不能读取,读取到的都是乱码,更别提写入了!
字符缓冲流
1
   | BufferedReader / BufferedWriter
 
  | 
 
高效读写、支持输入换行符、可一次写一行读一行

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | package IO.fileStream;
  import java.io.*;
  public class Demo06 {     public static void main(String[] args) throws IOException {                  FileReader fileReader = new FileReader("e://writer.txt");         BufferedReader bufferedReader = new BufferedReader(fileReader);                  
 
 
 
 
                   String line=null;         while ((line=bufferedReader.readLine())!=null){             System.out.println(line);         }                  bufferedReader.close();     } }
 
  | 
 


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | package IO.charStream;
  import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.Writer;
  public class Demo05 {     public static void main(String[] args) throws IOException {                  FileWriter fileWriter = new FileWriter("e://writer.txt");         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);                  for (int i = 0; i < 6; i++) {             bufferedWriter.write("Java是世界上最好的语言!");             bufferedWriter.write("\n");             bufferedWriter.flush();         }                  bufferedWriter.close();     } }
 
  | 
 

打印流(PrintWriter)
封装了print() / println() 方法 支持写入后换行
支持数据原样打印

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | package IO.fileStream;
  import java.io.FileNotFoundException; import java.io.PrintWriter;
  public class Demo07 {     public static void main(String[] args) throws FileNotFoundException {                  PrintWriter printWriter = new PrintWriter("e://printwriter.txt");                  printWriter.write(97);         printWriter.println(98);         printWriter.println('a');         printWriter.println('最');         printWriter.append((char) 97);                  printWriter.close();         System.out.println("进程完毕!");     } }
 
  | 
 

转换流
桥转换流 InputStreamReader / OutputStreamWriter
可将字节流转换为字符流
可设置字符的编码方式

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | package IO.fileStream;
  import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader;
  public class Demo08 {     public static void main(String[] args) throws IOException {                  FileInputStream fileInputStream = new FileInputStream("e://a.jpg");         InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");                  int data=0;         while ((data=inputStreamReader.read())!=-1){             System.out.println(data);         }                  inputStreamReader.close();     } }
 
  | 
 


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
   | package IO.fileStream;
  import java.io.*;
  public class demo09 {     public static void main(String[] args) throws IOException {                  FileInputStream fileInputStream = new FileInputStream("e://a.jpg");         InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");                  FileOutputStream fileOutputStream = new FileOutputStream("e://c.jpg");         OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"GBK");                  int data=0;         while ((data=inputStreamReader.read())!=-1){                          System.out.println(data);             outputStreamWriter.write(data);             outputStreamWriter.flush();         }
          inputStreamReader.close();         outputStreamWriter.close();
          System.out.println("储存完毕");
      } }
 
  | 
 

7.File类
概念:代表物理盘符中的一个文件或者文件夹

文件操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
   | package IO.File; import javax.xml.crypto.Data; import java.io.File; import java.util.Date;
 
 
 
 
  public class Demo01 {     public static void main(String[] args) throws Exception {         separator();         touchFile("e://a.txt");                           catFileInfo("e://a.txt");         judgeFile("e://a.txt");     }          public static void separator(){         System.out.println("路径分隔符:" + File.pathSeparator);         System.out.println("名称分隔符:" + File.separator);     }               public static void touchFile(String url) throws Exception {         File file = new File(url);         if (!file.exists()) {             System.out.println("创建结果:" + file.createNewFile());         } else {             System.out.println("文件已存在!");         }     }          public static void removeFile(String url)throws Exception{         File file = new File(url);         if (file.exists()){             System.out.println("删除结果:"+file.delete());         }else{             System.out.println("文件不存在呀,主人!");         }     }          public static void jvmRemove(String url) throws InterruptedException {         File file = new File(url);         if (file.exists()){             file.deleteOnExit();             Thread.sleep(5000);         }else{             System.out.println("文件不存在呀,主人!");         }     }          public static void catFileInfo(String url){         File file = new File(url);         if (file.exists()){             System.out.println("文件的绝对路径:"+file.getAbsoluteFile());             System.out.println("文件的路径:"+file.getPath());             System.out.println("文件名称:"+file.getName());             System.out.println("文件的父目录:"+file.getParent());             System.out.println("文件的长度:"+file.length());             System.out.println("文件的修改时间:"+(new Date(file.lastModified()).toLocaleString()));         }else{             System.out.println("文件不存在呀,主人!");         }     }          public static void judgeFile(String url) throws InterruptedException {         File file = new File(url);         if (file.exists()){             System.out.println("文件可读:"+file.canRead());             System.out.println("文件可写:"+file.canWrite());             System.out.println("文件可执行:"+file.canExecute());             System.out.println("是否是文件"+file.isFile());             System.out.println("文件是否隐藏了:"+file.isHidden());         }else{             System.out.println("文件不存在呀,主人!");         }     }      }
 
  | 
 
文件夹操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
   | package IO.File;
  import java.io.File; import java.util.Date;
  public class Demo02 {     public static void main(String[] args) throws Exception {                                    catDirInfo("e://aaa");     }          public static void separator(){         System.out.println("路径分隔符:" + File.pathSeparator);         System.out.println("名称分隔符:" + File.separator);     }               public static void touchDir(String url) throws Exception {         File dir = new File(url);         if (!dir.exists()) {             System.out.println("创建结果:" + dir.mkdir());         } else {             System.out.println("文件已存在!");         }     }          public static void removeDir(String url)throws Exception{         File dir = new File(url);         if (dir.exists()){             System.out.println("删除结果:"+dir.delete());         }else{             System.out.println("文件不存在呀,主人!");         }     }          public static void jvmRemove(String url) throws InterruptedException {         File dir = new File(url);         if (dir.exists()){             dir.deleteOnExit();             Thread.sleep(5000);         }else{             System.out.println("文件不存在呀,主人!");         }     }          public static void catDirInfo(String url){         File dir = new File(url);         if (dir.exists()){             System.out.println("文件夹的绝对路径:"+dir.getAbsolutePath());             System.out.println("文件夹的路径:"+dir.getPath());             System.out.println("文件夹名称:"+dir.getName());             System.out.println("文件夹的父目录:"+dir.getParent());             System.out.println("文件夹的修改时间:"+(new Date(dir.lastModified()).toLocaleString()));         }else{             System.out.println("文件不存在呀,主人!");         }     }          public static void judgeDir(String url) throws InterruptedException {         File dir = new File(url);         if (dir.exists()){             System.out.println("文件可读:"+dir.canRead());             System.out.println("文件可写:"+dir.canWrite());             System.out.println("文件可执行:"+dir.canExecute());             System.out.println("是否是文件夹"+dir.isDirectory());             System.out.println("文件是否隐藏了:"+dir.isHidden());         }else{             System.out.println("文件不存在呀,主人!");         }     } }
 
  | 
 

递归遍历文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | package IO.File;
  import java.io.File; import java.util.Date;
  public class Demo02 {     public static void main(String[] args) throws Exception {         listDir("e://");     }          public static void listDir(String url){         File dir = new File(url);         String[] list = dir.list();         for (String s : list) {             System.out.println(s);         }     } }
 
  | 
 

递归删除文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
   | package IO.File;
  import java.io.File; import java.net.URL; import java.util.Date;
  public class Demo02 {     public static void main(String[] args) throws Exception {         deleteDir("e://aaa");          	     public static void deleteDir(String url){         File dir = new File(url);         File[] files = dir.listFiles();         int count=files.length;         if(files != null && files.length > 0){             for(File file : files){                 System.out.println(file+"删除结果:"+file.delete());                 count--;             }         }
          if(count==0) {             dir.delete();             System.out.println("删除完成!");         }     } }
 
  | 
 

FileFilter接口
这是一个功能界面,因此可以用作lambda表达式或方法引用的赋值对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   |  package IO.File;
  import java.io.File; import java.io.FileFilter;
  public class Demo03 {     public static void main(String[] args) {         File dir = new File("C:\\Users\\Bai\\Pictures");         File[] files = dir.listFiles(new FileFilter() {             @Override             public boolean accept(File pathname) {                 if (pathname.getName().endsWith("jpg")){                     return true;                  }else{                     return false;                 }             }         });         for (File file : files) {             System.out.println(file.getName());         }     } }
 
 
  | 
 

8.小结

二、Java集合框架

1.集合的概念
- 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
 
和数组区别


常见集合分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | Collection 接口的接口 对象的集合(单列集合) ├——-List 接口:元素按进入先后有序保存,可重复 │—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全 │—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全 │—————-└ Vector 接口实现类 数组, 同步, 线程安全 │ ———————-└ Stack 是Vector类的实现类 └——-Set 接口: 仅接收一次,不可重复,并做内部排序 ├—————-└HashSet 使用hash表(数组)存储元素 │————————└ LinkedHashSet 链表维护元素的插入次序 └ —————-TreeSet 底层实现为二叉树,元素排好序
  Map 接口 键值对的集合 (双列集合) ├———Hashtable 接口实现类, 同步, 线程安全 ├———HashMap 接口实现类 ,没有同步, 线程不安全- │—————–├ LinkedHashMap 双向链表和哈希表实现 │—————–└ WeakHashMap ├ ——–TreeMap 红黑树对所有的key进行排序 └———IdentifyHashMap
 
  | 
 
2.Collection接口
Collection体系集合

Collection父接口

Collection的简单使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
   | package aggregate.Collection;
  import java.util.ArrayList; import java.util.Iterator;
  public class Demo01 {          
      public static void main(String[] args) {                  ArrayList<Object> collection = new ArrayList<>();                  collection.add("冰冰");         collection.add("Lisa");         collection.add("IU");         collection.add("书欣");         collection.add("白小飞");                  System.out.println(collection.size());                  System.out.println(collection);
                   collection.remove("白小飞");                  System.out.println("老婆的个数:"+collection.size());                  System.out.println(collection);
                            
 
 
 
          System.out.println("===增强for循环遍历====");         for (Object o : collection) {             System.out.println(o);         }         System.out.println("===Iterator遍历====");         Iterator iterator = collection.iterator();         while (iterator.hasNext()) {             String string = (String) iterator.next();             System.out.println(string);                                       iterator.remove();         }         System.out.println("======判断======");         System.out.println(collection.isEmpty());         System.out.println(collection.contains("白小飞"));
          System.out.println("====删除集合全部元素=====");                  collection.clear();                  System.out.println(collection.isEmpty());                  System.out.println(collection);
      } }
 
  | 
 

内存分析

3.List集合
List子接口
特点:有序、有下标、元素可以重复。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
   | package aggregate.List;
  import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator;
 
  public class Demo01 {     public static void main(String[] args) {
                   ArrayList arrayList = new ArrayList();                  arrayList.add("小米");         arrayList.add("小米");         arrayList.add("苹果");         arrayList.add("华为");
          System.out.println("========按照索引进行添加============");         arrayList.add(0,"荣耀");                  System.out.println(arrayList.size());         System.out.println(arrayList.toString());                  arrayList.remove("小米");         System.out.println(arrayList.toString());         System.out.println("===========按照下标索引进行删除==========");         arrayList.remove(1);         System.out.println(arrayList.toString());                  System.out.println("========普通for循环遍历==========");         for (int i = 0; i < arrayList.size(); i++) {             System.out.println(arrayList.get(i));         }         System.out.println("======增强for循环遍历========");         for (Object o : arrayList) {             System.out.println(o);         }         System.out.println("=======迭代器======");         Iterator iterator = arrayList.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }         System.out.println("=========列表迭代器从前往后=========");         ListIterator listIterator = arrayList.listIterator();         while (listIterator.hasNext()){             System.out.println(listIterator.nextIndex()+":"+listIterator.next());         }         System.out.println("=========列表迭代器从后往前=========");         while (listIterator.hasPrevious()){             System.out.println(listIterator.previousIndex()+":"+listIterator.previous());         }         System.out.println("==========判断=========");         System.out.println(arrayList.contains("小米"));         System.out.println(arrayList.contains("荣耀"));         System.out.println("=========获取元素位置==========");         System.out.println(arrayList.indexOf("华为"));     } }
 
  | 
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   | package aggregate.List;
  import java.util.ArrayList; import java.util.List;
  public class Demo02 {     public static void main(String[] args) {         List arrayList = new ArrayList();
                   arrayList.add(10);         arrayList.add(30);         arrayList.add(10);         arrayList.add(50);
          arrayList.remove(0);         System.out.println(arrayList.toString());         System.out.println("========通过数值进行删除的方法=======");         arrayList.remove((Object) 10);         System.out.println(arrayList.toString());         arrayList.remove(new Integer(50));         System.out.println(arrayList.toString());
                   arrayList.add(10);         arrayList.add(30);         arrayList.add(10);         arrayList.add(50);
          System.out.println("添加数据后:"+arrayList);         System.out.println("=======返回子集合=====");         List list = arrayList.subList(2,3);                  System.out.println(list);     } }
 
  | 
 

List的实现类
ArrayList(重点)
- 数组结构实现,查询快、增删慢;
 
- JDK1.2版本,运行效率快、线程不安全。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
   | package aggregate.List.ArrayList;
  import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator;
 
 
  public class Demo01 {     public static void main(String[] args) {         ArrayList arrayList = new ArrayList();                  Student g1 = new Student("冰冰", 18);         Student g2 = new Student("虞书欣", 18);         Student g3 = new Student("李知恩", 18);         Student g4 = new Student("白小飞", 18);
          arrayList.add(g1);         arrayList.add(g2);         arrayList.add(g3);         arrayList.add(0,g4);
          System.out.println(arrayList.toString());
          arrayList.remove(2);
          System.out.println("=====迭代器======");         Iterator iterator = arrayList.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next().toString());         }         System.out.println("=====列表迭代器======");         ListIterator listIterator = arrayList.listIterator();         while (listIterator.hasNext()){             System.out.println(listIterator.next().toString());         }         System.out.println("反向List迭代器");         while (listIterator.hasPrevious()){             System.out.println(listIterator.previous().toString());         }         System.out.println("=======判断=======");         System.out.println(arrayList.contains("白小飞"));         System.out.println(arrayList.toString());         System.out.println("========找位置=======");         System.out.println(arrayList.indexOf("白小飞"));
      } }
 
  | 
 

删除元素 arrayList.remove(new Student("name", 10));
这里重写了 equals(this == obj) 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public boolean equals(Object obj){      if(this == obj){     return true;   }      if(obj == null){     return false;   }      if(obj instanceof Student){     Student == (Student)obj;          if(this.name.equals(s.getName()) && this.age == s.getAge()){       return true;     }   }      return false; }
 
  | 
 
原码分析
DEFAULT_CAPACITY = 10; //默认容量

注意:如果没有向集合中添加任何元素时,容量0;添加一个后,容量为10;每次扩容是原来的1.5倍




elementData存放元素的数组
size 实际元素个数

Vector(向量)
- 数组结构实现,查询快、增删慢;。
 
- JDK1.0版本,运行效率慢、线程安全。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
   | package aggregate.List.Vector;
  import java.util.*;
  public class Demo01 {     public static void main(String[] args) {         System.out.println("====创建===");         Vector vector = new Vector<>();         System.out.println("====添加元素===");         vector.add("王冰冰");         vector.add("Lisa");         vector.add("白小飞");         vector.add("王冰冰");         vector.add("IU");         System.out.println("===删除元素===");         vector.remove("白小飞");         vector.remove(0);         System.out.println("===打印集合===");         System.out.println(vector.toString());         System.out.println("===普通for遍历===");         for (int i = 0; i < vector.size(); i++) {             System.out.println(vector.get(i));         }         System.out.println("===增强for遍历===");         for (Object o : vector) {             String str = (String)o;             System.out.println(str);         }         System.out.println("===普通迭代器===");         Iterator iterator = vector.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }         System.out.println("===List迭代器遍历===");         ListIterator listIterator = vector.listIterator();         while (listIterator.hasNext()){             System.out.println(listIterator.next().toString());         }         System.out.println("===List反向迭代器遍历===");         while (listIterator.hasPrevious()){             System.out.println(listIterator.previousIndex()+":"+listIterator.previous());         }         System.out.println("===特有枚举器===");         Enumeration elements = vector.elements();         while (elements.hasMoreElements()){             System.out.println((String)elements.nextElement());         }         System.out.println("===判断冰冰是否存在===");         System.out.println(vector.contains("王冰冰"));         System.out.println("===判断是否为空===");         System.out.println(vector.isEmpty());         System.out.println("===获取第一个元素===");         System.out.println(vector.firstElement());         System.out.println("===获取最后一个元素===");         System.out.println(vector.lastElement());         System.out.println("===获取下标为2的元素===");         System.out.println(vector.elementAt(2));     } }
 
  | 
 

LinkedList

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
   | package aggregate.List.LinkedList;
  import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator;
 
 
  public class Demo01 {     public static void main(String[] args) {         System.out.println("===创建集合===");         LinkedList linkedList = new LinkedList<>();         System.out.println("===添加元素===");         Student stu1 = new Student("白小飞", 10);         Student stu2 = new Student("杨洪利", 10);         Student stu3 = new Student("哈哈哈", 10);         linkedList.add(stu1);         linkedList.add(stu2);         linkedList.add(stu3);         System.out.println("===输出长度及数据===");         System.out.println(linkedList.size());         System.out.println(linkedList.toString());         System.out.println("====删除数据===");         linkedList.remove(2);         System.out.println(linkedList.toString());         System.out.println("===for遍历===");         for (int i = 0; i < linkedList.size(); i++) {             System.out.println(linkedList.get(i));         }         System.out.println("===增强for遍历===");         for (Object o : linkedList) {             Student o1 = (Student) o;             System.out.println(o1);         }         System.out.println("===普通迭代器===");         Iterator iterator = linkedList.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next().toString());         }         System.out.println("===listIterator迭代器===");         ListIterator listIterator = linkedList.listIterator();         while (listIterator.hasNext()){             System.out.println(listIterator.next());         }         System.out.println("===listIterator反向迭代器===");         while (listIterator.hasPrevious()){             System.out.println(listIterator.previous().toString());         }         System.out.println("===判断并获取===");         System.out.println(linkedList.contains("白小飞"));         System.out.println(linkedList.indexOf(stu1));     } }
 
  | 
 

源码分析
int size():集合的大小
Node first:链表的头节点!
Node last:链表的尾节点



remove速度快:只是改变节点关系,数据不需要移动


不同结构实现方式

ArrayList:必须开辟连续空间,查询快,增删慢。
 
LinkedList:无需开辟连续空间,查询慢,增删快。
 
List与数组转化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | 
  package aggregate.List;
  import java.util.ArrayList; import java.util.Arrays; import java.util.List;
  public class Demo03 {     public static void main(String[] args) {         List<Integer> list = new ArrayList<>();         list.add(1);         list.add(2);         Integer[] array = list.toArray(new Integer[10]);         Integer[] array1 = list.toArray(new Integer[2]);         System.out.println("objects1 == objects2 : "+(array == array1));         System.out.println("show array: "+ Arrays.toString(array));         System.out.println("show array1: "+ Arrays.toString(array1));         System.out.println("show list: "+list);     } }
 
  | 
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | package aggregate.List;
  import java.util.Arrays; import java.util.List;
 
 
  public class Demo04 {     public static void main(String[] args) {         String[] students = {"宰相","皇帝","大臣","御史大夫"};         List<String> strings = Arrays.asList(students);                                             System.out.println(strings);     } }
 
  | 
 
这个集合是受限集合,不支持增加删除操作!

1 2 3 4 5
   |  Integer[] nums01={1,2,3,5,6}; List<Integer> integers = Arrays.asList(nums01);
  System.out.println(integers);
 
  | 
 
拓展
Java中int和Integer关系是比较微妙的。关系如下:
- int是基本的数据类型,Integer是int的封装类(复杂数据类型);
 
- int和Integer都可以表示某一个数值;
 
- int和Integer不能够互用,因为他们两种不同的数据类型;
 
- 在类进行初始化时int类的变量初始为0.而Integer的变量则初始化为null
 
小结:只是用来进行一些加减乘除的运算or作为参数进行传递,那么就可以直接声明为int基本数据类型,但如果要像对象一样来进行处理,那么就要用Integer来声明一个对象,因为java是面向对象的语言,因此当声明为对象时能够提供很多对象间转换的方式。
4.泛型
泛型
本质是参数化类型,把类型作为参数传递
语法: <T,…..>成为类型占位符,表示一种引用类型,可以写多个逗号隔开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | package aggregate.SegmentFault;
 
 
 
 
  public class Demo01<T> {
                T t;          public void print(T t){         System.out.println(t);     }          public T getT(){         return t;     }
  }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | package aggregate.SegmentFault;
 
  public class TestDemo01 {     public static void main(String[] args) {         Demo01<String> demo01 = new Demo01<>();         demo01.t="hello";         demo01.print("大家好");         System.out.println(demo01.getT());
          Demo01<Integer> integerDemo01 = new Demo01<>();         integerDemo01.t=12;         integerDemo01.print(15);         System.out.println(integerDemo01.getT());     } }
 
  | 
 
注意:1.泛型只能使用引用类型;2.不同泛型类型对象不能相互赋值
1 2 3 4 5 6 7 8 9 10 11
   |  package aggregate.SegmentFault;
 
 
  public interface Demo02<K> {
      String name="白小飞";
      K server(K k); }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12
   |  package aggregate.SegmentFault;
 
  public class Demo02Impl01 implements Demo02<String>{
      @Override     public String server(String s) {         System.out.println(s);         return s;     } }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11
   |  package aggregate.SegmentFault;
 
  public class Demo02Impl02<T> implements Demo02<T>{     @Override     public T server(T t) {         System.out.println(t);         return t;     } }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12
   |  package aggregate.SegmentFault;
  public class TestDemo02 {     public static void main(String[] args) {         Demo02Impl01 demo02 = new Demo02Impl01();         demo02.server("白小飞");
          Demo02Impl02<String> demo02Impl02 = new Demo02Impl02<>();         demo02Impl02.server("hello");     } }
 
  | 
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | package aggregate.SegmentFault;
 
 
  public class Demo03 {     public <t> void say(){         System.out.println("say!");     }
      public <T> T haha(T t){         System.out.println(t);         return t;     } }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12
   | package aggregate.SegmentFault;
 
 
  public class TestDemo03 {     public static void main(String[] args) {         Demo03 demo03 = new Demo03();         demo03.say();         demo03.haha("中国加油!");         demo03.haha(111);     } }
 
  | 
 
好处 
- 提高代码重用性 ,类似于重载,一个方法可以传递各种参数!
 
- 防止类型转换异常,提高代码安全性
 
泛型集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | package aggregate.SegmentFault;
  import java.util.Iterator; import java.util.LinkedList;
  public class Demo04 {     public static void main(String[] args) {         System.out.println("原迭代器遍历");         LinkedList<Object> objects = new LinkedList<>();         objects.add("划水");         objects.add("摸鱼");         objects.add("吃饭");         objects.add(555);         objects.add(666);         Iterator<Object> iterator = objects.iterator();                                                         
          LinkedList<Integer> integers = new LinkedList<>();         integers.add(1);         integers.add(4);         integers.add(3);         integers.add(2);         Iterator<Integer> iterator1 = integers.iterator();         while (iterator1.hasNext()){             System.out.println(iterator1.next());         }
          Student stu1 = new Student("白小飞", 12);         Student stu2 = new Student("冰冰", 12);         Student stu3 = new Student("虞书欣", 12);         Student stu4 = new Student("IU", 12);         LinkedList<Student> students = new LinkedList<>();         students.add(stu1);         students.add(stu2);         students.add(stu3);         students.add(stu4);         Iterator<Student> iterator2 = students.iterator();         while (iterator2.hasNext()){             System.out.println(iterator2.next());         }     } }
 
  | 
 

5.Set集合
Set接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | package aggregate.Set.HashSet;
  import java.util.HashSet; import java.util.Iterator; import java.util.Set;
  public class Demo01 {          
      public static void main(String[] args) {                  Set<String> hashSet = new HashSet<>();                           hashSet.add("白小飞");         hashSet.add("白小飞");         hashSet.add("王冰冰");         hashSet.add("吃花椒");         hashSet.add("喵酱");         System.out.println(hashSet.size());         System.out.println(hashSet.toString());                                    System.out.println("===使用增强for===");         for (String s : hashSet) {             System.out.println(s);         }
          System.out.println("===使用迭代器===");         Iterator<String> iterator = hashSet.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }         System.out.println("===判断===");         System.out.println(hashSet.contains("王冰冰"));     } }
 
  | 
 

Set实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   | package aggregate.Set.HashSet;
  import java.util.HashSet; import java.util.Iterator;
 
 
  public class Demo02 {     public static void main(String[] args) {                  HashSet<String> hashSet = new HashSet<>();                  hashSet.add("王冰冰");         hashSet.add("蔡徐坤");         hashSet.add("双厨");         hashSet.add("央视");         System.out.println(hashSet.size());         System.out.println(hashSet);                  hashSet.remove("央视");         hashSet.add("央视");         System.out.println(hashSet);         System.out.println("===增强for迭代===");         for (String s : hashSet) {             System.out.println(s);         }         System.out.println("===迭代器===");         Iterator<String> iterator = hashSet.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }         System.out.println("===判断===");         System.out.println(hashSet.contains("蔡徐坤"));     }
  }
 
  | 
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
   | package aggregate.Set.HashSet;
  import java.util.HashSet; import java.util.Iterator;
  public class Demo03 {     public static void main(String[] args) {                  HashSet<Person> people = new HashSet<Person>();         Person p1 = new Person("白小飞", 11);         Person p2 = new Person("qdwq", 11);         Person p3 = new Person("qdqw", 11);         Person p4 = new Person("caixe", 11);                  people.add(p1);         people.add(p2);         people.add(p3);         people.add(p4);         people.add(new Person("lisa",18));                           people.add(new Person("白小飞", 11));                  System.out.println(people.toString());         System.out.println("===增强for循环===");         for (Person person : people) {             System.out.println(person.toString());         }         System.out.println("===迭代器循环===");         Iterator<Person> iterator = people.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }     } }
 
  | 
 

存储过程(重复依据)
- 根据hashCode计算保存的位置,如果位置为空,直接保存,若不为空,进行第二步
 
- 再执行equals方法,如果equals为true,则认为是重复,否则形成链表
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | 
  @Override     public boolean equals(Object o) {         if (this == o) return true;         if (o == null || getClass() != o.getClass()) return false;         Person person = (Person) o;         return age == person.age && Objects.equals(name, person.name);     }
      @Override     public int hashCode() {         return Objects.hash(name, age);     }
 
  | 
 
在hashCode方法中存在了一个31,它的作用:
1.31是一个质数,尽量减少散列冲突
2.31提高执行效率 31*i=i<<5-i (将乘法换成移位操作,底层计算,效率快)

TreeSet
- 基于排列顺序实现元素不重复
 
- 实现了SortedSet接口,对集合元素自动排序
 
- 元素对象的类型必须实现Comparable接口,指定排序规则
 
- 通过CompareTo方法确定是否为重复元素
 

普通数据默认比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   | package aggregate.TreeSet;
  import java.util.Iterator; import java.util.TreeSet;
 
 
  public class Demo01 {     public static void main(String[] args) {         TreeSet<String> treeSet = new TreeSet<String>();         treeSet.add("asda");         treeSet.add("xya");         treeSet.add("ii");         treeSet.add("a");         System.out.println("个数:"+treeSet.size());         System.out.println(treeSet.toString());         System.out.println("===增强for===");         for (String s : treeSet) {             System.out.println(s);         }         System.out.println("===迭代器===");         Iterator<String> iterator = treeSet.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }     } }
 
  | 
 

实现 Comparable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
   |  package aggregate.TreeSet;
  import java.util.Objects;
  public class Person implements Comparable<Person> {     private String name;     private int age;
      public Person(String name, int age) {         this.name = name;         this.age = age;     }
      public String getName() {         return name;     }
      public void setName(String name) {         this.name = name;     }
      public int getAge() {         return age;     }
      public void setAge(int age) {         this.age = age;     }
      @Override     public String toString() {         return "Person{" +                 "name='" + name + '\'' +                 ", age=" + age +                 '}';     }
           @Override     public int compareTo(Person o) {         int name=this.name.compareTo(o.name);         int age=this.age-o.age;         return name==0?age:name;     }
      @Override     public boolean equals(Object o) {         if (this == o) return true;         if (o == null || getClass() != o.getClass()) return false;         Person person = (Person) o;         return age == person.age && Objects.equals(name, person.name);     }
      @Override     public int hashCode() {         return Objects.hash(name, age);     } }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | package aggregate.TreeSet;
  import java.util.Iterator; import java.util.TreeSet;
 
 
 
  public class Demo02 {     public static void main(String[] args) {         TreeSet<Person> people = new TreeSet<>();         Person p1 = new Person("xyz", 11);         Person p2 = new Person("lisa",11);         Person p3 = new Person("bai",11);         Person p4 = new Person("iu",11);         people.add(p1);         people.add(p2);         people.add(p3);         people.add(p4);         System.out.println(people.size());         System.out.println(people.toString());         Person p5 = new Person("iu",18);         Person p6 = new Person("iu",18);         people.add(p5);         people.add(p6);         System.out.println(people.toString());         for (Person person : people) {             System.out.println(person.toString());         }         Iterator<Person> iterator = people.iterator();         while (iterator.hasNext()){             System.out.println(iterator.next());         }                           System.out.println(people.toString());         people.add(new Person("iu",11));         System.out.println(people.toString());         people.remove(new Person("iu",18));         System.out.println(people.toString());     } }
 
  | 
 

Comparator 实现定制比较(定制器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
   | package aggregate.TreeSet;
 
  import java.util.Comparator; import java.util.TreeSet;
  public class Demo03 {     public static void main(String[] args) {                           TreeSet<Person> people = new TreeSet<>(new Comparator<Person>() {             @Override             public int compare(Person o1, Person o2) {                 int n1 = o1.getName().compareTo(o2.getName());                 int n2 = o1.getAge()-o2.getAge();                 return n1==0?n2:n1;             }         });
          Person p1 = new Person("xyz", 11);         Person p2 = new Person("lisa",11);         Person p3 = new Person("bai",11);         Person p4 = new Person("iu",11);
          people.add(p1);         people.add(p2);         people.add(p3);         people.add(p4);
          System.out.println(people);     } }
 
  | 
 

example
要求:使用TreeSet集合实现字符串长度排序
compare :
1:前面的数>后面的数,是降序(从大到小)排列,如果想要改为升序排列,就需要返回1
-1:前面的数<后面的数,是升序(从小到大)排列,不改变位置就返回-1;
0:二者相等,不进行交换,也就不排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | package aggregate.TreeSet;
  import java.util.Comparator; import java.util.TreeSet;
  public class Demo04 {     public static void main(String[] args) {         TreeSet<String> strings = new TreeSet<>(new Comparator<String>() {             @Override             public int compare(String o1, String o2) {                 int n1=o1.length()-o2.length();                                                                                                      int n2=o1.compareTo(o2);                                  return n1==0?n2:n1;             }         });         strings.add("aaaa");         strings.add("zasas");         strings.add("asasd");         strings.add("ada");         strings.add("wd");         System.out.println(strings);     } }
 
  | 
 

6.Map集合


Map父接口
Map接口的特点
- 用于存储任意键值对(key - value)
 
- 键:无序、无下标、不允许重复(唯一)
 
- 值:无序、无下标、允许重复
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
   | package aggregate.Map;
  import java.util.HashMap; import java.util.Map; import java.util.Set;
 
 
  public class Demo01 {     public static void main(String[] args) {         HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();         stringIntegerHashMap.put("白小飞",18);         stringIntegerHashMap.put("葫芦娃",18);         stringIntegerHashMap.put("哈哈哈",18);         stringIntegerHashMap.put("嘎嘎嘎",18);         System.out.println(stringIntegerHashMap.toString());         System.out.println("===不会增加重复元素,但是会更新value值===");         stringIntegerHashMap.put("白小飞",21);         System.out.println(stringIntegerHashMap.toString());         System.out.println("===keySet遍历===");         Set<String> strings = stringIntegerHashMap.keySet();         for (String string : strings) {             System.out.println(string+":"+stringIntegerHashMap.get(string));         }         System.out.println("===entrySet遍历===");         Set<Map.Entry<String, Integer>> entries = stringIntegerHashMap.entrySet();         for (Map.Entry<String, Integer> entry : entries) {             System.out.println(entry.getKey()+":"+entry.getValue());         }         System.out.println("===判断key与value是否存在===");         System.out.println(stringIntegerHashMap.containsKey("白小飞"));         System.out.println(stringIntegerHashMap.containsValue(18));     } }
 
  | 
 

KeySet与EntrySet
entrySet效率较高,可一次性查出key与value。

Map集合的实现类
HashMap(重点)

- 存储结构:哈希表(数组+链表+红黑树)
 
- 使用key可使hashcode和equals作为重复
 
- 增、删、遍历、判断与上述一致
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
   |  package aggregate.Map.HashMap;
  import java.util.Objects;
  public class Student {     private String name;     private int stuNo;
      public Student() {     }
      public Student(String name, int stuNo) {         this.name = name;         this.stuNo = stuNo;     }
      public String getName() {         return name;     }
      public void setName(String name) {         this.name = name;     }
      public int getStuNo() {         return stuNo;     }
      public void setStuNo(int stuNo) {         this.stuNo = stuNo;     }
      @Override     public String toString() {         return "Student{" +                 "name='" + name + '\'' +                 ", stuNo=" + stuNo +                 '}';     }
      @Override     public boolean equals(Object o) {         if (this == o) return true;         if (o == null || getClass() != o.getClass()) return false;         Student student = (Student) o;         return stuNo == student.stuNo && Objects.equals(name, student.name);     }
      @Override     public int hashCode() {         return Objects.hash(name, stuNo);     } }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
   | 
  package aggregate.Map.HashMap;
  import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set;
 
 
 
  public class Demo01 {     public static void main(String[] args) {         HashMap<Student, String> studentStringHashMap = new HashMap<>();                  Student stu01 = new Student("孙悟空", 100);         Student stu02 = new Student("猪八戒", 102);         Student stu03 = new Student("唐三藏", 103);         studentStringHashMap.put(stu01,"上海");         studentStringHashMap.put(stu02,"杭州");         studentStringHashMap.put(stu03,"北京");         System.out.println("元素个数:"+studentStringHashMap.size());         System.out.println(studentStringHashMap.toString());         studentStringHashMap.put(new Student("沙和尚",122),"北京");         System.out.println("元素个数:"+studentStringHashMap.size());         System.out.println(studentStringHashMap.toString());         System.out.println("===添加重复元素===");          studentStringHashMap.put(new Student("唐三藏", 103),"北京");         System.out.println("元素个数:"+studentStringHashMap.size());         System.out.println(studentStringHashMap.toString());         studentStringHashMap.remove(stu01);         System.out.println(studentStringHashMap);                  System.out.println("===keySet遍历===");         Set<Student> students = studentStringHashMap.keySet();         for (Student student : students) {             System.out.println(student+":"+studentStringHashMap.get(student));         }         System.out.println("===entrySet遍历===");         Set<Map.Entry<Student, String>> entries = studentStringHashMap.entrySet();         for (Map.Entry<Student, String> entry : entries) {             System.out.println(entry.getKey()+":"+entry.getValue());         }         System.out.println("===判断是否存在===");         System.out.println(studentStringHashMap.containsValue("泰安"));                  System.out.println(studentStringHashMap.containsKey(new Student("唐三藏", 103)));     } }
 
  | 
 

原码分析

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   |  static final int DEFAULT_INITAL_CAPACITY = 1 << 4;
 
  static final int MAXMUM_CAPACITY = 1 << 30;
 
  static final float DEFAULT_LOAD_FACTOR = 0.75f;
 
  static final int TREEIFYTHRESHOLD = 8;
 
  static final int UNTREEIFY_THRESHOLD = 6;
 
  static final int MIN_TREEIFY_CAPACITY = 64;
 
  transient Node<K, V>[] table;
 
  transient Set<Map.Entry<K, V>> entrySet;
 
  transient int size;
 
  | 
 
- 刚创建hashSet时table=null size=0以节省空间
 

1 2 3
   | Node<K,V>[] tab; Node<K,V> p; int n, i;         if ((tab = table) == null || (n = tab.length) == 0)             n = (tab = resize()).length;
 
  | 
 
1 2 3 4
   | if (++size > threshold)             resize();         afterNodeInsertion(evict);         return null;
 
  | 
 
源码分析总结
- HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
 
- 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
 
- jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
 
- jdk1.8 当链表长度 <6 时 调整成链表
 
- jdk1.8 以前,链表时头插入,之后为尾插入
 

HashMap与HashSet



HashSet实现了 Set接口,不允许出现重复元素,但是向HashSet中存储对象必须重写对象的HashCode和equals方法。HashSet是由HashMap实现的。HashSet允许存储NULL元素,并且NULL永远存储在第一个。

HashMap实现了Map接口,允许NULL键NULL值。使用hash寻址会发生hash冲突问题,底层使用数组加链表的结构,解决了冲突也均衡了查找和增删的效率;一般将数组中的每一个元素称作桶(segment)。

HashTable
线程安全,运行效率慢;不允许null作为key或是value
Properties(属性集合)
hashtable的子类,要求key和value都是string,通常用于配置文件的读取
特点:
- 1.存储属性名和属性值
 
- 2.属性名和属性值都是字符串类型
 
- 3.没有泛型
 
- 和流有关
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
   | package aggregate.Map;
  import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import java.util.Properties; import java.util.Set;
  public class PropertiesDemo {     public static void main(String[] args) throws IOException {                  Properties properties = new Properties();                  properties.setProperty("username","zhangsan");         properties.setProperty("age","18");         System.out.println(properties.toString());                           Set<Object> objects = properties.keySet();         for (Object o : objects) {             System.out.println(o+":"+properties.getProperty((String) o));         }                  Set<Map.Entry<Object, Object>> entries = properties.entrySet();         System.out.println(entries.toString());                  Set<String> strings = properties.stringPropertyNames();         for (String string : strings) {             System.out.println(string+":"+properties.getProperty(string));         }
                                              
                                     
          System.out.println("==========");                  Properties properties1 = new Properties();         FileInputStream fileInputStream = new FileInputStream("e://abc.txt");         properties1.load(fileInputStream);         fileInputStream.close();         System.out.println(properties1.toString());     } }
 
  | 
 

TreeMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
   | package aggregate.Map.TreeMap;
  import java.util.Comparator; import java.util.Map; import java.util.Set; import java.util.TreeMap;
 
  public class Demo01 {     public static void main(String[] args) {                  TreeMap<Student, Integer> studentIntegerTreeMap = new TreeMap<>(new Comparator<Student>() {             @Override             public int compare(Student o1, Student o2) {                 int n1=o1.getStuNo()-o2.getStuNo();                 return n1;             }         });         Student s1 = new Student("白小飞", 120);         Student s2 = new Student("呜呜呜", 121);         Student s3 = new Student("杨洪利", 123);         studentIntegerTreeMap.put(s1,11);         studentIntegerTreeMap.put(s2,12);         studentIntegerTreeMap.put(s3,15);         System.out.println(studentIntegerTreeMap.toString());         studentIntegerTreeMap.put(new Student("杨洪利", 123),88);         System.out.println(studentIntegerTreeMap.toString());         System.out.println("===删除===");         studentIntegerTreeMap.remove(s3);         System.out.println(studentIntegerTreeMap.toString());         System.out.println("===keyset遍历===");         Set<Student> students = studentIntegerTreeMap.keySet();         for (Student student : students) {             System.out.println(student.toString()+":"+studentIntegerTreeMap.get(student));         }         System.out.println("===entryset遍历===");         Set<Map.Entry<Student, Integer>> entries = studentIntegerTreeMap.entrySet();         for (Map.Entry<Student, Integer> entry : entries) {             System.out.println(entry.getKey()+":"+entry.getValue());         }         System.out.println("===判断===");         System.out.println(studentIntegerTreeMap.containsKey(new Student("白小飞", 120)));         System.out.println(studentIntegerTreeMap.containsValue(12));     } }
 
  | 
 

7.Collections工具类
此类仅由静态方法组合或返回集合。  它包含对集合进行操作的多态算法,“包装器”,返回由指定集合支持的新集合,以及其他一些可能的和最终的。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | package aggregate.Collection;
  import java.util.ArrayList; import java.util.Collections; import java.util.List;
 
  public class Demo03 {     public static void main(String[] args) {         List list = new ArrayList<>();         list.add(1);         list.add(2);         list.add(3);         list.add(8);                  System.out.println(list.toString());                  Collections.sort(list);                  System.out.println("排序后:"+list.toString());                  System.out.println(Collections.binarySearch(list, 8));         System.out.println(Collections.binarySearch(list, 0));                  ArrayList arrayList = new ArrayList<>();         for (int i = 0; i < list.size(); i++) {             arrayList.add(i);         }         System.out.println("由于collections.copy()需要相同长度,添加数据后");         System.out.println("arraryList:"+arrayList.toString());         Collections.copy(arrayList,list);         System.out.println("copy后的数据:"+arrayList);         System.out.println("reserve倒序");         Collections.reverse(list);         System.out.println("reserve:"+list);         System.out.println("乱序排列");         Collections.shuffle(list);         System.out.println("乱序后:"+list);
      } }
 
  | 
 

三、Java常见类
参考