Java进阶学习

一、IO框架学习

img

1.流的概念

内存与存储设备之间传输数据的通道

2.流的分类

按方向【重点】

  • 输入流:将<存储设备>中的内容读到<内存>中
  • 输出流:将<内存>中的内容写到<存储设备>中

按单位

  • 字节流:以字节为单位,可以读写所有数据
  • 字符流:以字符为单位,只能读写文本数据

按功能

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础之上增强功能

3.字节流

字节流的父类(抽象类)

1
2
3
4
5
6
7
8
9
// InputStream 字节输入流
public int read(){}
public int read(byte[] b){}
public int read(byte[] b, int off, int len){}

// OutputStream 字节输出流
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b, int off, int len){}

文件字节流

文件输入流

image-20210206200455088

image-20210206201009753

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 {
// 1 创建FileInputStream 并指定文件路径
FileInputStream fileInputStream = new FileInputStream("e://a.txt");
//2.读取文件 返回-1证明读取完毕
//int a=fileInputStream.read();
//System.out.println(a);
//3.循环读取 单字节读取!
//int data=0;
//while ((data=fileInputStream.read())!=-1){
// System.out.println((char) data);
//}
//4.多字节读取
//每次读取3个字节

/*
byte[] str=new byte[3];
int read = fileInputStream.read(str);
System.out.println("实际读取的个数:"+read);
System.out.println(new String(str));
int read02 = fileInputStream.read(str);
System.out.println("实际读取的个数:"+read02);
System.out.println(new String(str));
*/
int count=0;
byte[] buff = new byte[4];
while ((count=fileInputStream.read(buff))!=-1){
System.out.println(new String(buff,0,count));
}
fileInputStream.close();
}
}

image-20210206112821062

拓展:new String()

1
new String(byte bytes[], int offset, int length) 

image-20210206112911463

image-20210206112950183

文件输出流

image-20210206200844885

image-20210206200932808

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 {
// 1 创建文件字节输出流
FileOutputStream fileOutputStream = new FileOutputStream("e://b.txt",true); // true表示不覆盖 接着写 默认为 false
// 2 写入文件
fileOutputStream.write(97);
fileOutputStream.write('c');
fileOutputStream.write('c');
fileOutputStream.write('\n');
// 3 写入字符串
String str = new String("helloworld");
fileOutputStream.write(str.getBytes(StandardCharsets.UTF_8));

fileOutputStream.close();
System.out.println("执行完毕!");
}
}

image-20210206114129823

图片复制案例

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 {
// 1 创建流
// 1.1 文件字节输入流
FileInputStream fileInputStream = new FileInputStream("e://a.jpg");
// 1.2 文件字节输出流
FileOutputStream fileOutputStream = new FileOutputStream("e://b.jpg");
// 2 边读边写
byte[] bytes = new byte[1024];
int count=0;
while ((count=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,count);
}
// 3 关闭
fileOutputStream.close();
fileInputStream.close();
System.out.println("执行完毕!");
}
}

image-20210206120047874

字节缓冲流

缓冲流:BufferedInputStream/ BufferedOutputStream

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

image-20210206201233858

image-20210206201317560

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 {
// 1 创建BufferedInputStream
FileInputStream fileInputStream = new FileInputStream("e://a.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
// 2 使用字节缓冲流读取
/*
int data= 0;
while ((data=bufferedInputStream.read())!=-1){
System.out.print((char) data);
}
System.out.println();
*/
// 3 自己写一个缓冲区
byte[] bytes = new byte[1024];
int count = 0;
while ((count=fileInputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,count));
}
// 4 只需要关闭缓冲流即可!
bufferedInputStream.close();
fileInputStream.close();
}
}

image-20210206121338879

image-20210206201425306

image-20210206201444489

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);
// 1 创建BufferedInputStream
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
String str = new String("helloworld");
// 2 写入文件
bufferedOutputStream.write(str.getBytes(StandardCharsets.UTF_8));// 写入8k缓冲区
bufferedOutputStream.flush();//刷新到硬盘
// 3 关闭缓冲流
bufferedOutputStream.close();
System.out.println("进程完成");
}
}

image-20210206130104830

4.对象流

1
ObjectOutputStream / ObjectInputStream
  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串的功能
  • 增强了读写对象的功能
    • readObject() 从流中读取一个对象
    • writeObject(Object obj) 向流中写入一个对象

使用流传输对象的过程称为序列化、反序列化

ObjectOutputStream

image-20210206202227118

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;
//ObjectStream序列化
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Demo01 {
public static void main(String[] args) throws IOException {
// 1 创建文件输出流
FileOutputStream fileOutputStream = new FileOutputStream("e://stu.bin");
// 2 创建对象输出流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 3 序列化
Student stu01 = new Student("张三", 18);
Student stu02 = new Student("李四", 18);
objectOutputStream.writeObject(stu01);
objectOutputStream.writeObject(stu02);
// 4 刷新
objectOutputStream.flush();
// 5 关闭
objectOutputStream.close();
System.out.println("序列化完毕!");
}
}

image-20210206143558626

1
2
3
//Student类需要实现 Serializable 接口 这个接口仅仅标识这个类可以实现序列化
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
//Student类
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 +
'}';
}
}

image-20210206144026110

ObjectInputStream

image-20210206202142434

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 {
// 使用ObjectInputSteam实现反序列化(读取重构对象)
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 1 创建文件输入流
FileInputStream fileInputStream = new FileInputStream("e://stu.bin");
// 2 创建对象流
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 3 读取文件(反序列化)
Student student01 = (Student) objectInputStream.readObject();
Student student02 = (Student) objectInputStream.readObject();
// 4 关闭
objectInputStream.close();
System.out.println("执行完毕!");
// 5 输出
System.out.println(student01.toString());
System.out.println(student02.toString());
}
}

Serializable 接口

类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。 可序列化类的所有子类型都是可序列化的。 序列化接口没有方法或字段,仅用于标识可串行化的语义。

注意事项

  1. 某个类要想序列化必须实现 Serializable接口
  2. 序列化类中对象属性要求实现 Serializable接口
  3. 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
  4. 使用transient修饰属性,这个属性就不能序列化
  5. 静态属性不能序列化
  6. 序列化多个对象,可以借助集合来实现
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();
}
}

image-20210206152312381

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();
}
}

image-20210206152234980

5.编码方式

常见编码

  • ASCII 码

    • 学过计算机的人都知道 ASCII 码,总共有 128 个,用一个字节的低 7 位表示,0~31 是控制字符如换行回车删除等;32~126 是打印字符,可以通过键盘输入并且能够显示出来。 
  • 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 有以下编码规则:
        1. 如果一个字节,最高位(第 8 位)为 0,表示这是一个 ASCII 字符(00 - 7F)。可见,所有 ASCII 编码已经是 UTF-8 了。
        2. 如果一个字节,以 11 开头,连续的 1 的个数暗示这个字符的字节数,例如:110xxxxx 代表它是双字节 UTF-8 字符的首字节。
        3. 如果一个字节,以 10 开始,表示它不是首字节,需要向前查找才能得到当前字符的首字节

Reader类

Reader 类是 Java 的 I/O 中读字符的父类,而 InputStream 类是读字节的父类,InputStreamReader 类就是关联字节到字符的桥梁,它负责在 I/O 过程中处理读取字节到字符的转换,而具体字节到字符的解码实现它由 StreamDecoder 去实现,在 StreamDecoder 解码过程中必须由用户指定 Charset 编码格式。值得注意的是如果你没有指定 Charset,将使用本地环境中的默认字符集,例如在中文环境中将使用 GBK 编码。

img

Writer类

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

img

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); //2个字 6个字节
}

fileInputStream.close();
}
}

image-20210206153512107

字符流的父类(抽象类)

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

image-20210206202729823

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 {
// 1 创建FileReader 文件字符输入流
FileReader fileReader = new FileReader("e://baixiao.txt");
// 2 单个字符读取
/*
int data=0;
while ((data=fileReader.read())!=-1){
System.out.println((char) data);// 读取一个字符
System.out.println(data);
}
*/
// 3 创建字符缓冲区读取
char[] chars = new char[2];
int data=0;
while ((data=fileReader.read(chars))!=-1){
System.out.println(new String(chars, 0, data));
}
// 4 关闭
fileReader.close();
}
}

image-20210206155532912

FileWriter

image-20210206202922983

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("执行完毕!");
}
}

image-20210206160023430

进行文本文件复制

不能复制图片或二进制文件(声音图片),但是使用字节流可以复制任意文件

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 {
// 1 创建
FileReader fileReader = new FileReader("e://hahah.txt");
FileWriter fileWriter = new FileWriter("e://hahah2.txt");
// 2 读写
int data=0;
while ((data=fileReader.read())!=-1){
fileWriter.write(data);
fileWriter.flush();
}
// 3 关闭
fileReader.close();
fileWriter.close();
System.out.println("读写完成");
}
}

image-20210206160818959

字符流不能读取图片原因分析:

二进制文件没有字符编码,不能读取,读取到的都是乱码,更别提写入了!

字符缓冲流

1
BufferedReader / BufferedWriter

高效读写、支持输入换行符、可一次写一行读一行

image-20210206203051802

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 {
// 1 创建缓冲流
FileReader fileReader = new FileReader("e://writer.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 2 读取
/*
int data=0;
while ((data=bufferedReader.read())!=-1){
System.out.print((char) data);
}
*/
// 3 readline()
String line=null;
while ((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
// 4 关闭
bufferedReader.close();
}
}

image-20210206164102160

image-20210206203204255

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 {
// 1. 创建BufferedWriter对象
FileWriter fileWriter = new FileWriter("e://writer.txt");
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 2. 写入
for (int i = 0; i < 6; i++) {
bufferedWriter.write("Java是世界上最好的语言!");
bufferedWriter.write("\n");// 写入一个换行符
bufferedWriter.flush();
}
// 3. 关闭
bufferedWriter.close();
}
}

image-20210206162729146

打印流(PrintWriter)

封装了print() / println() 方法 支持写入后换行

支持数据原样打印

image-20210206203330231

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 {
// 1 创建打印流
PrintWriter printWriter = new PrintWriter("e://printwriter.txt");
// 2 打印
printWriter.write(97);
printWriter.println(98);
printWriter.println('a');
printWriter.println('最');
printWriter.append((char) 97);
// 3 关闭
printWriter.close();
System.out.println("进程完毕!");
}
}

image-20210206165158917

转换流

桥转换流 InputStreamReader / OutputStreamWriter

可将字节流转换为字符流

可设置字符的编码方式

image-20210206203459727

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 {
// 1 创建InputStreamReader对象
FileInputStream fileInputStream = new FileInputStream("e://a.jpg");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
// 2 读取文件
int data=0;
while ((data=inputStreamReader.read())!=-1){
System.out.println(data);
}
// 3 关闭
inputStreamReader.close();
}
}

image-20210206170457804

image-20210206203718881

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 {
// 1 创建InputStreamReader对象
FileInputStream fileInputStream = new FileInputStream("e://a.jpg");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
// 2 OutputStreamWriter对象
FileOutputStream fileOutputStream = new FileOutputStream("e://c.jpg");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"GBK");
// 3 读取文件
int data=0;
while ((data=inputStreamReader.read())!=-1){
// 4 写入文件
System.out.println(data);
outputStreamWriter.write(data);
outputStreamWriter.flush();
}

inputStreamReader.close();
outputStreamWriter.close();

System.out.println("储存完毕");

}
}

image-20210206172130157

7.File类

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

image-20210206203811980

文件操作

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;

//File类的使用
//1. 分隔符
//2. 文件操作
//3. 文件夹操作
public class Demo01 {
public static void main(String[] args) throws Exception {
separator();
touchFile("e://a.txt");
//removeFile("e://a.txt");
//jvmRemove("e://a.txt");
catFileInfo("e://a.txt");
judgeFile("e://a.txt");
}
// 1 分隔符
public static void separator(){
System.out.println("路径分隔符:" + File.pathSeparator);
System.out.println("名称分隔符:" + File.separator);
}
// 2 文件操作
// 2.1 创建文件
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("文件已存在!");
}
}
// 2.2 删除文件
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("文件不存在呀,主人!");
}
}
// 2.3 使用JVM退出时删除文件
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("文件不存在呀,主人!");
}
}
// 3 获取文件信息
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("文件不存在呀,主人!");
}
}
// 4 判断
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 {
//touchDir("e://aaa");
//removeDir("e://aaa");
//jvmRemove("e://aaa");
catDirInfo("e://aaa");
}
// 1 分隔符
public static void separator(){
System.out.println("路径分隔符:" + File.pathSeparator);
System.out.println("名称分隔符:" + File.separator);
}
// 2 文件操作
// 2.1 创建文件
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("文件已存在!");
}
}
// 2.2 删除文件夹(只能删除空目录)
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("文件不存在呀,主人!");
}
}
// 2.3 使用JVM退出时删除文件
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("文件不存在呀,主人!");
}
}
// 3 获取文件信息
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("文件不存在呀,主人!");
}
}
// 4 判断
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("文件不存在呀,主人!");
}
}
}

image-20210206185534150

递归遍历文件夹

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://");
}
// 5 遍历文件夹
public static void listDir(String url){
File dir = new File(url);
String[] list = dir.list();
for (String s : list) {
System.out.println(s);
}
}
}

image-20210206190739847

递归删除文件夹

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("删除完成!");
}
}
}

image-20210206192810593

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
//FileFilter接口的使用
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; //符合条件返回true
}else{
return false;
}
}
});
for (File file : files) {
System.out.println(file.getName());
}
}
}

image-20210206195109460

8.小结

img

二、Java集合框架

000

1.集合的概念

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。

和数组区别

  • 数组长度固定,集合长度不固定

  • 数组可以存储基本类型和引用类型,集合只能存储引用类型

差异

  • 位置: java.util.*;

java.long.object

常见集合分类

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父接口

20180803193423722

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 {
//Collection接口的使用
//添加元素--删除元素--遍历元素--判断元素

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());
//打印collection
System.out.println(collection);

//删除元素
collection.remove("白小飞");
//打印元素个数
System.out.println("老婆的个数:"+collection.size());
//打印collection
System.out.println(collection);

//遍历集合
//增强for循环,不能使用普通for,因为没有下标
/*
for (int i = 0; i < collection.size(); i++) {
System.out.println(collection[i]);
}
*/
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);
// 在迭代过程中不允许使用collection.remove()方法
//collection.remove(string); ConcurrentModificationException:collection
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());
//打印collection
System.out.println(collection);

}
}

image-20210203114152624

内存分析

image-20210203220859635

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;

//List接口的使用
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("华为"));
}
}

image-20210203223533429

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);
//List list02 = arrayList.subList(2,6); 越界
System.out.println(list);
}
}

image-20210203224825285

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;

//ArrayList的使用
//存储结构:数组 ,查找 遍历速度快,增删慢
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("白小飞"));

}
}

image-20210203231141392

删除元素 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){
//1 判断是不是同一个对象
if(this == obj){
return true;
}
//2 判断是否为空
if(obj == null){
return false;
}
//3 判断是否是Student类型
if(obj instanceof Student){
Student == (Student)obj;
//4 比较属性
if(this.name.equals(s.getName()) && this.age == s.getAge()){
return true;
}
}
//5 不满足条件返回false
return false;
}

原码分析

DEFAULT_CAPACITY = 10; //默认容量

image-20210204122210858

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

image-20210204122841574

image-20210204123132586

image-20210204123351858

image-20210204123414185

elementData存放元素的数组

size 实际元素个数

image-20210204122719123

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));
}
}

image-20210204162119291

LinkedList
  • 链表结构实现,增删快,查询慢。

LinkedLis

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;

//LinkedList
//存储结构:双向链表
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));
}
}

image-20210204163335185

源码分析

int size():集合的大小

Node first:链表的头节点!

Node last:链表的尾节点

image-20210204164057185

image-20210204164142424

image-20210204164212640

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

image-20210204164655690

LinkedLis

不同结构实现方式

image-20210204165047435

  • ArrayList:必须开辟连续空间,查询快,增删慢。

  • LinkedList:无需开辟连续空间,查询慢,增删快。

List与数组转化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//list.toArrary()

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);
}
}

image-20210205204801334

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);
//strings.add("秦王");
//strings.remove("宰相");
System.out.println(strings);
}
}

这个集合是受限集合,不支持增加删除操作!

image-20210205205543031

1
2
3
4
5
//把基本类型数组转成集合时,需要修改为包装类型
Integer[] nums01={1,2,3,5,6};
List<Integer> integers = Arrays.asList(nums01);
//List<int[]> integers02 = Arrays.asList(nums01);
System.out.println(integers);

拓展

Java中int和Integer关系是比较微妙的。关系如下:

  1. int是基本的数据类型,Integer是int的封装类(复杂数据类型);
  2. int和Integer都可以表示某一个数值;
  3. int和Integer不能够互用,因为他们两种不同的数据类型;
  4. 在类进行初始化时int类的变量初始为0.而Integer的变量则初始化为null

小结:只是用来进行一些加减乘除的运算or作为参数进行传递,那么就可以直接声明为int基本数据类型,但如果要像对象一样来进行处理,那么就要用Integer来声明一个对象,因为java是面向对象的语言,因此当声明为对象时能够提供很多对象间转换的方式。

4.泛型

泛型

本质是参数化类型,把类型作为参数传递

语法: 成为类型占位符,表示一种引用类型,可以写多个逗号隔开

  • 泛型类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package aggregate.SegmentFault;

//泛型类
//语法:类名<T>
//T表示类型占位符,可以有多个

public class Demo01<T> {

//泛型可以用于创建变量,但是不能实例化对象 new
//使用泛型创建变量
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
//Demo02
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;

//继承string类型的范型类接口
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
//main()
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");
}
}

image-20210204213633053

  • 泛型方法
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. 防止类型转换异常,提高代码安全性

泛型集合

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();
//while (iterator.hasNext()){
//System.out.println(iterator.toString());
//String str = (String) iterator.next();
//System.out.println(str);
//}

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());
}
}
}

image-20210204224544183

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 {
//测试 Set 接口的使用
//特点:无序 、没有下标 、 不能重复

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());
//删除操作
//hashSet.remove("白小飞");
//遍历
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("王冰冰"));
}
}

image-20210204234823341

Set实现类

  • HashSet
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;

//HashSet
//存储结构:哈希表(数组+链表+红黑树)
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("蔡徐坤"));
}

}

image-20210204235919868

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));
//下面new又存储了一个相同的元素!!
//存了两个白小飞!!
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());
}
}
}

image-20210205001302866

存储过程(重复依据)

  1. 根据hashCode计算保存的位置,如果位置为空,直接保存,若不为空,进行第二步
  2. 再执行equals方法,如果equals为true,则认为是重复,否则形成链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//方法重写 可以通过new进行remove删除以及不能通过new重复存储了 
//alt+insert 重写 hasCode 和 equal方法
@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 (将乘法换成移位操作,底层计算,效率快)

image-20210205115837148

TreeSet

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

TreeSet

普通数据默认比较
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;
//使用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());
}
}
}

image-20210205125205703

实现 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
//Person
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;
//使用TreeSet保存数据
//存储结构:红黑树
//要求:元素必须要实现 Comparable接口,CompareTo() 返回值为0,认为是重复元素

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());
}
//重写hashSet方法后,将不会储存重复的new 对象
//重写hashSet方法后,可以通过new 对象删除具有相同属性的元素
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());
}
}

image-20210205130919657

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;

//Comparator 定制比较
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);
}
}

image-20210205132114298

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();
//n1 == 0 说明 长度相等
//compare :
//1:前面的数>后面的数,是降序(从大到小)排列,如果想要改为升序排列,就需要返回1
//-1:前面的数<后面的数,是升序(从小到大)排列,不改变位置就返回-1;
//0:二者相等,不进行交换,也就不排序。
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);
}
}

image-20210205133802895

6.Map集合

map集合

image-20210205135518032

Map父接口

Map接口的特点

  1. 用于存储任意键值对(key - value)
  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
package aggregate.Map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

//Map接口的使用
//特点:(1)存储键值对;(2)键不能重复,值可以重复;(3)无序
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));
}
}

image-20210205143743861

KeySet与EntrySet

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

image-20210205143246792

Map集合的实现类

HashMap(重点)

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
//Student
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
//Application

package aggregate.Map.HashMap;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

//HashMap集合
//存储结构:哈希表(数组+链表+红黑树)
//使用hashCode 和 equals 方法
public class Demo01 {
public static void main(String[] args) {
HashMap<Student, String> studentStringHashMap = new HashMap<>();
//key值不可以重复,但是value值可以!value值也会覆写!!
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("===添加重复元素==="); //重写hashCode 和 equals 方法实现不允许存储重复数据
studentStringHashMap.put(new Student("唐三藏", 103),"北京");
System.out.println("元素个数:"+studentStringHashMap.size());
System.out.println(studentStringHashMap.toString());
studentStringHashMap.remove(stu01);
System.out.println(studentStringHashMap);
//studentStringHashMap.clear();
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("泰安"));
//由于重写了equals 和 hashSet 方法, 所以可以通过 new 一个具有相同属性的对象 删除原有元素
System.out.println(studentStringHashMap.containsKey(new Student("唐三藏", 103)));
}
}

image-20210205152510536

原码分析

image-20210205182956377

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
//默认的初始化容量为16
static final int DEFAULT_INITAL_CAPACITY = 1 << 4;

//最大的容量,容量的值必须是2的幂并且小于最大容量,最大值为2的30此房
static final int MAXMUM_CAPACITY = 1 << 30;

//加载因子默认值为0.75
static final float DEFAULT_LOAD_FACTOR = 0.75f;

//计数阀值,超过这个值将会使用树形结构替代链表结构
static final int TREEIFYTHRESHOLD = 8;

//由树形结构转换成链表结构的阀值
static final int UNTREEIFY_THRESHOLD = 6;

//树形结构最小容量为64
static final int MIN_TREEIFY_CAPACITY = 64;

//链表数组
transient Node<K, V>[] table;

//HashMap中value的集合
transient Set<Map.Entry<K, V>> entrySet;

//hashMap的长度
transient int size;
  • 刚创建hashSet时table=null size=0以节省空间

image-20210205182303236

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;
源码分析总结
  1. HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
  2. 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
  3. jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
  4. jdk1.8 当链表长度 <6 时 调整成链表
  5. jdk1.8 以前,链表时头插入,之后为尾插入

HashMap

HashMap与HashSet

image-20210205185143373

image-20210205185231505

image-20210205185254562

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

HashSet

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

HashMap

HashTable

线程安全,运行效率慢;不允许null作为key或是value

Properties(属性集合)

hashtable的子类,要求key和value都是string,通常用于配置文件的读取

特点:

  • 1.存储属性名和属性值
  • 2.属性名和属性值都是字符串类型
  • 3.没有泛型
  • 和流有关

image-20210206214707613

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 {
// 1 创建集合
Properties properties = new Properties();
// 2 添加数据
properties.setProperty("username","zhangsan");
properties.setProperty("age","18");
System.out.println(properties.toString());
// 3 遍历
// 3.1 keySet
Set<Object> objects = properties.keySet();
for (Object o : objects) {
System.out.println(o+":"+properties.getProperty((String) o));
}
// 3.2 entrySet
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
System.out.println(entries.toString());
// 3.3 stringPropertyNames
Set<String> strings = properties.stringPropertyNames();
for (String string : strings) {
System.out.println(string+":"+properties.getProperty(string));
}

// 4 和流有关的方法
// 4.1 properties.list(printWriter)
//PrintWriter printWriter = new PrintWriter("e://abc.txt");
//properties.list(printWriter);
//printWriter.close();

// 4.2 properties.store(printWriter,"注释");
//PrintWriter printWriter = new PrintWriter("e://xyz.txt");
//properties.store(printWriter,"注释");
//printWriter.close();

System.out.println("==========");
// 4.3 properties.load(fileInputStream);
Properties properties1 = new Properties();
FileInputStream fileInputStream = new FileInputStream("e://abc.txt");
properties1.load(fileInputStream);
fileInputStream.close();
System.out.println(properties1.toString());
}
}

image-20210206214418402

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;

//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));
}
}

image-20210205193328064

7.Collections工具类

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

image-20210205211930624

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;

//Collections工具类
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());
//binarySearch
System.out.println(Collections.binarySearch(list, 8));
System.out.println(Collections.binarySearch(list, 0));
//copy复制
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);

}
}

image-20210205212108002

三、Java常见类

参考


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!