需要注意
变量
- 成员变量(在类里面声明)在声明时可以不给它初始化,编译器会自动给这个成员变量初始化,但局部变量(在方法里面声明)在声明时一定要给它初始化,因为编译器不会自动给局部变量初始化,任何变量在使用之前必须对它进行初始化。
常用类
1 内部类
在一个类的内部再定义一个完整的类
- 特点
内部类可直接访问外部类的私有成员,而不破坏封装。
可为外部类提供必要的内部功能组件。
1.1 成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类。
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
- Outer out = new Outer();
- Inner in = out.new Inner();
或者 - Inner in = new Outer().new Inner();
- 当外部类、内部类存在重名 属性时,会优先访问内部类属性。
- 成员内部类不能定义静态成员。(但是可以包含静态常量,final)
1.2 局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
- 不能加任何访问修饰符
1.3 匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)
- 必须继承一个父类或者实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
- 优点:减少代码量
- 缺点:可读性较差
Public class TestUsb {
public static void mian(String[] args) {
// 创建接口类型的变量
Usb usb1 = new Mouse();
usb1.service();
// 局部内部类
class Keyboard implements Usb{
@Override
public void service() {
System.out.println("连接电脑成功,键盘开始工作了");
}
}
// 使用局部内部类创建对象
Usb usb2 = new Keyboard();
usb2.service();
// 使用匿名内部类优化(相当于创建了一个局部内部类),接口不能实例化的
Usb usb3 = new Usb() {
@Override
public void service() {
System.out.println("连接电脑成功,风扇开始工作了");
}
}
}
}
public interface Usb {
// 服务
void service();
}
public class Mouse implements Usb {
@Override
public void service() {
System.out.println("连接电脑成功,鼠标开始工作了");
}
}
2 Object类
- 基类,所有类的直接或间接父类,位于继承树的最顶层。
- 任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类。
- Object类中所定义的方法,是所有对象都具备的方法。
- Object类型可以存储任何对象。
- 作为参数,可接受任何对象;
- 作为返回值,可返回任何对象。
1.1 getClass()方法
- public final Class<?> getClass(){}
- 返回引用中存储的实际对象类型
- 应用:通常用于判断两个引用中实际存储对象类型是否一致
Student s1 = new Student("a", 20);
Student s2 = new Student("b", 22);
// 判断s1和s2是不是同一个类型
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if (Class1 == CLass2) {
System.out.println("s1和s2属于同一个类型");
} else {
System.out.println("s1和s2不属于同一个类型");
}
}
1.2 hashCode()方法
- public int hashCode() {}
- 返回该对象的哈希码值。
- 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值。
- 一般情况下相同对象返回相同哈希码。
1.2 toString()方法
- public String toString() {}
- 返回该对象的字符串表示(表示形式)
1.3 equals()方法
- public boolean equals (Object obj) {}
- 默认实现为(this == obj),比较两个对象地址是否相同
- 可进行重写,比较两个对象的内容是否相同
1.4 finanlize()方法
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
- 垃圾对象:没有有效引用指向此对象时,为垃圾对象。
- 垃圾回收:由GC销毁垃圾对象,释放数据 存储空间。
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
- 手动回收机制:使用System.gc();通知JVM执行垃圾回收。
@Override
protected void finalize() throws Throwable{
sout(this.name + "对象被回收了");
}
psvm(String[] args){
Student s1 = new Student("aaa", 29); // 不是垃圾
new Student("bbb", 30); // 是辣鸡 会被回收
//回收垃圾
System.gc();
sout("回收垃圾");
// 打印出 “回收垃圾
// bbb对象被回收了”
}
3 包装类
- 基本数据类型所对应的引用数据类型
- Object可统一所有数据,包装类的默认值是null
基本数据类型 | 包装类型 | 内存(位) | 默认值 |
---|---|---|---|
byte | Byte | 8 | 0 |
short | short | 16 | 0 |
int | Integer | 32 | 0 |
long | Long | 64 | 0L |
float | Float | 32 | 0.0f |
double | Double | 64 | 0.0d |
boolean | Boolean | 16 | false |
char | Character | 8 | \u0000 |
类型转换与装箱拆箱
- 8种包装类提供不用类型间的转换方式
- Number父类中提供的6个共性方法
- parseXXX( )静态方法
- valueOf( )静态方法
- Number父类中提供的6个共性方法
- 注意:需保证类型兼容,否则抛出NumberFormatException异常
psvm(String[] args){
// 装箱, 基本类型 → 引用类型
// 基本类型
int num1 = 18;
// 使用Integer类创建对象
Integer integer1 = new Integer(num1);
Integer integer2 = Integer.valueOf(num1);
// 拆箱, 引用类型 → 基本类型
Integer integer3 = new Integer(100);
int num2 = integer3.intValue();
// jdk1.5之后提供了自动装箱拆箱
int age = 30;
// 自动装箱
Integer integer4 = age;
// 自动拆箱
int age2 = integer4;
// 基本类型和字符串之间转换
// 1. 基本类型转成字符串
int n1 = 100;
// 1.1 使用+号
String s1 = n1 + "";
// 1.2 使用Integer中的toString()方法
String s2 = Integer.toString(n1);
String s2 = Integer.toString(n1, x); // x为进制要求
// 2. 字符串转成基本类型
String str = "150";
// 使用Integer.parseXXX();
int n2 = Integer.parseInt(str);
// boolean 字符串形式转成基本类型,"true" ---> true 非“true ———> false
String str2 = "true";
boolean b1 = Boolean.parseBoolean(str2);
}
整数缓存区
- Java预先创建了256个常用的整数包装类型对象
- 在实际应用当中,对已创建的对象进行复用
psvm(String[] args){
// 面试题
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
sout(integer1 == integer2); // false
Integer integer3 = 100;// 自动装箱
// 相当于调用 Integer.valueOf(100);
Integer integer4 = 100;
sout(integer3 == integer4); // true
Integer integer5 = 200;// 自动装箱
Integer integer6 = 200;
sout(integer5 == integer6); // false
// 因为缓存区数组 [-128, 127] 在这之内地址一样
}
4 String类
- 字符串是常量,创建之后不可改变
- 字符串字面值存储在字符串池中,可以共享
String s = "Hello";
产生一个对象,字符串池中存储String s = new String("Hello");
产生两个对象,堆、池各一个
常用方法
// 1. length(); 返回字符串长度,(空格也算)
// 2. charAt(int index); 返回某个位置的字符
// 3. contains(String str); 判断是否包含某个字符串
String content = "java是最好的语言, java no1";
sout(content.length()); // 10
sout(content.charAt(content.length() - 1)); // 言
sout(content.contains("java")); // true
// 4. toCharArray(); 返回字符串对应数组
// 5. indexOf(); 返回子字符串首次出现的位置
// 6. lastIndexOf(); 返回字符串最后一次出现的位置
sout(content.toCharArray());
sout(content.indexOf"java")); // 0
sout(content.indexOf("java", 4)); // 从索引4开始找 返回12
sout(content.lastIndexOf("java")); // 12
// 7. trim(); //去掉字符串前后空格
// 8. toUpperCase(); toLowerCase(); 转换大小写
// 9. endWith(str); startWith(str); 判断是否以str 结尾、开头
String ct = " hello world ";
sout(ct.trim()); // "hello world"
sout(ct.toUpperCase()); // HELLO WORLD
sout(ct.toLowerCase()); // hello world
String ct1 = "hello world";
sout(ct1.endWith("world")); // true
sout(ct1.startWith("hello")) // true
// 10. replace(char old, char new); 用新的字符或字符串替换旧的字符或字符串
// 11. split(); 对字符串拆分
sout(content.replace("java", "php")); // php是最好的语言, php no1
String say = "java is the best language";
String[] arr = say.split(" "); // "[ ,]+" 表示空格 逗号切分 +号表示切分可以多个 比如多个空格
sout(arr.length); // 5
for(String string : arr){
sout(string);
}
// 打印出
//java
//is
//the
//best
//language
// 补充两个equals/compareTo();比较大小
String s1 = "hello";
String s2 = "HELLO";
sout(s1.equalsIgnoreCase(s2));// 忽略大小写比较true
// compareTo(); 两字符不同时比较字符字典序的ascii码,若第一个相等则比较后面的
String s3 = "abc"; //97 (字符串首字符)
String s4 = "xyzawe" //120
sout(s3.compareTo(s4)); //-23
// 字符相同时比较长度 返回差值,
String s5 = "abc"; //字符串长度3
String s6 = "abcxyz" //字符串长度6
sout(s3.compareTo(s4)); //-3
练习
String str = "this is a text";
// 将str中的单词单独获取出来
String[] arr = str.split(" ");
for (String a : arr){
System.out.println(a);
}
// 将str中的text替换为practice
System.out.println(str.replace("text","practice"));
// 在text前面插入一个easy
System.out.println(str.replace("text","easy text"));
// 将每个单词的首字母改为大写
for(int i = 0; i < arr.length; i++){
char first = arr[i].charAt(0);
char upfirst = Character.toUpperCase(first);
String news = upfirst + arr[i].substring(1);
System.out.println(news);
}
StringBuffer和StringBuilder
- StringBuffer:可变长字符串,运行效率慢,线程安全。
StringBuilder:可变长字符串,运行效率快,线程不安全。 - 特殊的方法:
append(); 追加
insert(0, “str”); 在指定位置添加
replace(0, 5, “str”); 在指定位置替换
delete(0, sb.length()); 在指定位置删除(清空)
5 BigDecimal
BigDecimal,大的浮点数精确计算()
double d1 = 1.0;
// 后面加的值用字符串
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
// 类之间就不能用减法了,用减法:subtract;加法:add;乘法:multiply;除法:divide
BigDecimal r1 = bd1.subtract(bd2);
// 0.1
sout(r1);
BigDecimal r2 = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
// 1
sout(r2);
// divide参数,保留3位小数,四舍五入, 否则会报错
BigDecimal r3 = new BigDecimal("10")
.divide(new BigDecimal("3"), 2, BigDecimal.ROUND_HALF_UP);
// 3.33
sout(r3);
6 Date
- Date表示特定的瞬间,精确到毫秒。(Date类中大部分方法都已被Calendar类中的方法所取代)
//创建Date对象
Date date1 = new Date();
// Sat Oct 09 10:27:37 CST 2021
sout(date1.toString());
7 Calendar
- Calendar提供了获取或设置各种日历字段的方法
- 构造方法
protected Calendar()
,由于修饰符是protected,所以无法直接创建该对象。
// 1创建Calendar对象
Calendar calendar = Calendar.getInstance();
// 2021-10-9 11:01:38
System.out.println(calendar.getTime().toLocaleString());
// 返回从格林威治标准时间到Calendar对象表示的时间之间的毫秒数
// 1633748498411
System.out.println(calendar.getTimeInMillis());
// 2获取时间信息
// 获取年
int year = calendar.get(Calendar.YEAR);
// 月,0-11
int month = calendar.get(Calendar.MONTH);
// 日
int day = calendar.get(Calendar.DAY_OF_MONTH);
// 小时,24小时制
int hour = calendar.get(Calendar.HOUR_OF_DAY);
// 分钟
int minute = calendar.get(Calendar.MINUTE);
// 秒
int second = calendar.get(Calendar.SECOND);
// 2021年10月9日11:1:38
System.out.println(year+"年"+(month+1)+"月"+day+"日"+hour+":"+minute+":"+second);
// 3修改时间
Calendar calendar2 = Calendar.getInstance();
calendar2.set(Calendar.DAY_OF_MONTH,5);
// 2021-10-5 11:01:38
System.out.println(calendar2.getTime().toLocaleString());
// 4增加时间add方法
calendar2.add(Calendar.HOUR,-1);
// 2021-10-5 10:01:38
System.out.println(calendar2.getTime().toLocaleString());
// 5补充方法,判断一个月中的最大/小天数
int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);
int min = calendar2.getActualMinimum(Calendar.DAY_OF_MONTH);
// 31
System.out.println(max);
// 1
System.out.println(min);
8 SimpleDateFormat
- SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类。
- 进行格式化(日期 -> 文本)、解析(文本 -> 日期)
- 常用的时间模式字母
字母 | 日期或时间 | 示例 |
---|---|---|
y | 年 | 2019 |
M | 年中月份 | 08 |
d | 月中天数 | 10 |
H | 小时(0-23) | 22 |
m | 分钟 | 16 |
s | 秒 | 59 |
S | 毫秒 | 367 |
public static void main(String[] args) throws ParseException {
// 1创建SimpleDateformat对象,y 年 m 月
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 2创建Date
Date date = new Date();
// 3格式化date(把日期转成字符串)
String str = sdf.format(date);
// 2021/10/09 13:38:30
System.out.println(str);
// 解析(把字符串转成日期),需要考虑异常
Date date2 = sdf.parse("1990/05/01 00:00:00");
// Tue May 01 00:00:00 CDT 1990
System.out.println(date2);
}
9 System类
- System系统类,主要用于获取系统的属性数据和其他操作,构造方法私有的,所以不需要创建对象,且大部分是静态的,可以直接用System.xx。
// 1数组复制arraycopy
// src:原数组
// srcPos:从哪个位置开始复制0
// dest:[目标数组]
// destPos:目标数组的位置
// length:复制的长度
int[] arr = {20, 18};
int[] dest = new int[4];
System.arraycopy(arr,0,dest,1,arr.length);
for(int i = 0; i <dest.length;i++) {
System.out.println(dest[i]);
}
// 0
// 20
// 18
// 0
// 2获取当前时间与标准时间所差的毫秒数,(可以相减记录程序运行时间)
long start = System.currentTimeMillis();
// 1633759161684
System.out.println(start);
集合框架
- 集合概念:对象的容器,定义了对多个对象进行操作的常用方法,可实现数组的功能。
- 和数组的区别:
(1)数组长度固定,集合长度不固定
(2)数组可以存储基本类型和引用类型,集合只能存储引用类型 - 集合位置:java.util.*
- 体系结构:
Collection父接口
- 特点:代表一组任意类型的对象,无序,无下标、不能重复。(部分相反)
- 方法:
boolean add(Object obj)
// 添加一个对象
boolean addAll(Collection c)
// 将一个集合中的所有对象添加到此集合
void clear()
// 清空此集合中的所有对象
boolean contains(Object o)
// 检查此集合是否包含o对象
boolean equals(Object o)
// 比较此集合是否与指定对象相等
boolean isEmpty()
// 判断此集合是否为空
boolean remove(Object o)
// 在此集合中移除o对象
int size()
// 返回此集合中的元素个数
Object[] toArray()
// 将此集合转换成数组
// 新建Collection对象
Collection collection = new ArrayList();
Student s1 = new Student("三",20);
Student s2 = new Student("四",18);
// 1增强for遍历,(元素对象要用Object类型)
for (Object object : collection) {
Student s = (Student)object;
sout(s.toString());
}
// 2迭代器:hasNext(),next(),remove();迭代过程中不能使用collection的删除方法
Iterator it = collection.iterator();
while(it.hasNext()) {
Student s = (Student)it.next();
sout(s.toString());
}
List子接口
- 特点:有序、有下标、元素可以重复
- 方法:
void add(int index, Object o)
// 在index位置插入对象o
boolean addAll(int index, Collection c)
// 将一个集合中的元素添加到此集合中的index位置
Object get(int index)
// 返回集合中指定位置的元素
List subList(int fromIndex, int toIndex)
// 返回fromIndex和toIndex之间的集合元素
List list = new ArrayList<>();
//1添加元素(自动装箱)
list.add("1");
list.add("2");
list.add("3");
// [1, 2]
sout(list.toString());
//2删除,下两种方法效果一样
// list.remove(0);
list.remove("1");
// [2]
sout(list.toString());
//3遍历
//3.1使用for遍历
// 2
// 3
for (int i = 0; i<list.size(); i++){
// get函数返回的是Object类型的,可强转
sout(list.get(i));
}
//3.2使用增强for,注意变量要用object
for (Object object : list) {
sout(object);
}
//3.3使用迭代器
Iterator it = list.iterator();
while (it.hasNext()) {
sout(it.next);
}
//3.4使用列表迭代器,可向前或向后遍历,添加,删除,修改元素
ListIterator lit = list.listItertor();
// 0: 2
// 1: 3
while (lit.hasNext()) {
sout(lit.nextIndex() + ": " + lit.next());
}
// 1: 3
// 0: 2
while (lit.hasPrevious()) {
sout(lit.previousIndex() + ": " + lit.previous());
}
//4判断
// true false
sout(list.contains("2"));
sout(list.isEmpty());
+添加数字数据
List<Integer> list = new ArrayList<>();
// 自动装箱
list.add(20);
list.add(30);
list.add(40);
System.out.println("个数:"+list.size());
System.out.println(list.toString());
// 三种删除方法一样的效果
list.remove(0);
// list.remove((Object)20);
// list.remove(new Integer(20));
System.out.println(list.toString());
// subList,返回子集合,含头不含尾
List<Integer> subList = list.subList(1, 2);
System.out.println(subList.toString());
List实现类
- ArrayList:
- 有序,有下标,可重复
- 数组结构实现。查询快,增删慢
- 运行效率快,线程不安全
- LinkesList:
- 链表结构实现,增删快,查询慢
ArrayList
- ArrayList相当于数组,不过它的长度是可变的,所以也称动态数组
//创建两个ArrayList类型数组
List<Integer> list = new ArrayList<>();
List<Integer> list1 = new ArrayList<>();
- isEmpty()
//判断动态数组是否为空,true
System.out.println(list.isEmpty());
- add()
//将数据存入动态数组
list.add(1);
list.add(2);
System.out.println(list);
//输出
[1, 2]
//在指定索引位置添加值
list.add(1, 3);
System.out.println(list);
//输出
[1, 3, 2]
- size()
//查看数组长度
System.out.println(list.size());
//输出
3
- contains()
//寻找数组中是否有某个值,true
System.out.println(list.contains(3));
- remove()
//寻找数组中是否有某个值
list.remove(1);
System.out.println(list);
//输出
[1, 2]
- set()
//修改指定索引位置的值
list.set(1, 10);
System.out.println(list);
//输出
[1, 10]
- get()
//获取指定索引位置的值
System.out.println(list.get(2));
//输出
10
- indexOf()
若动态数组中有该值,若没有,返回-1;若有多个相同的数值,则返回第一个值得索引值
//查找数组中是否有值为2
System.out.println(indexOf.(2));
//查找数组中是否有值为10
System.out.println(indexOf.(10));
//输出
-1
1
- addAll()
将一个动态数组中的值全部加到另一个动态数组中
//另一个数组添加值
list1.add(5);
list1.add(6);
System.out.println(list);
System.out.println(list1);
//输出
[1, 10]
[5, 6]
//将list1中所有元素加入到list中
list.addAll(list1);
System.out.println(list);
//输出
[1, 10, 5, 6]
- containsAll()
//判断一个动态数组是否完全包含另一个动态数组, true
System.out.println(list.containAll(list1));
- removeAll()
//移除两个容器中都含有的元素
list.removeAll(list1);
System.out.println(list);
//输出
[1, 10]
- retainAll()
list.add(6);
//取出两个动态数组中相同的部分
list.retainAll(list1);
System.out.println(list);
//输出
[6]
- clear()
//清理动态数组中所有的值
list.clear();
- ArrayList源码分析:
DEFAULT_CAPACITY = 10;默认容量
注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素之后,容量为10;每次扩容大小是原来的1.5倍。
elementData存放元素的数组
size 实际元素个数
add() 添加元素
LinkedList
存储结构:双向链表
LinkedList linklist = new LinkedList<>();
//1新增
linklist.add("a");
linklist.add("2");
linklist.add("3");
// 3 [a, 2, 3]
System.out.println(linklist.size());
System.out.println(linklist);
//2删除
linklist.remove("a");
// [2, 3]
System.out.println(linklist);
//3遍历,增强for
// 2 3
for (Object s : linklist) {
System.out.println(s);
}
//4判断
// true false
System.out.println(linklist.contains("2"));
System.out.println(linklist.isEmpty());
//5获取
1
System.out.println(linklist.indexOf("3"));
泛型
- 泛型本质是参数化类型,把类型作为参数传递
- 常见形式有泛型类,泛型接口,泛型方法
- 语法
- <T, …> T称为类型占位符,表示一种引用类型
泛型类
/**
* 泛型类
* 语法:类名<T>
* T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
*/
class MyGemeric<T> {
// 使用泛型T
// 1创建变量
T t;
// 2泛型作为方法的参数
public void show(T t) {
System.out.println(t);
}
// 3泛型作为方法的返回值
public T getT() {
return t;
}
}
public class chapter {
public static void main(String[] args) {
// 使用泛型类创建对象
// 注意:1泛型只能使用引用类型,2不同泛型类型对象之间不能互相赋值
MyGemeric<String> myGemeric = new MyGemeric<>();
myGemeric.t = "hello";
// 大家好,我是Vea
myGemeric.show("大家好,我是Vea");
String string = myGemeric.getT();
MyGemeric<Integer> myGemeric2 = new MyGemeric<>();
myGemeric2.t=100;
// 200
myGemeric2.show(200);
Integer integer = myGemeric2.getT();
}
}
泛型接口
/**
* 泛型接口
* 语法:接口名<T>
* 不能创建泛型静态常量
*/
interface MyInterface<T> {
String name = "三";
T server(T t);
}
class MyInterfaceImp implements MyInterface<String> {
@Override
public String server(String t) {
System.out.println(t);
return t;
}
}
class MyInterfaceImpl2<T> implements MyInterface<T> {
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
public class chapter {
public static void main(String[] args) {
MyInterfaceImp impl = new MyInterfaceImp();
impl.server("XXX");
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
impl2.server(1000);
}
}
泛型方法
/**
* 泛型接口
* 语法:<T> 返回值类型
*/
class MyGenericMethod {
// 泛型方法,也可用静态方法
public <T> T show(T t) {
System.out.println("泛型方法");
return t;
}
}
public class chapter {
public static void main(String[] args) {
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("qwer");
myGenericMethod.show(200);
}
}
泛型集合
- 使用集合时尽量使用泛型集合。
- 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
- 避免类型转换集合的异常
public class chapter {
public static void main(String[] args) {
// 限制集合类型为String
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("q");
arrayList.add("w");
// 非String类型的对象添加不进去
// arrayList.add(1);
for (String string : arrayList) {
System.out.println(string);
}
}
}
Set集合
Set子接口
- 特点:无序,无下标,元素不可重复。
- 方法:全部继承自Collection中的方法。
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// 1添加数据
set.add("小米");
set.add("苹果");
set.add("华为");
System.out.println("数据个数:"+set.size());
System.out.println(set.toString());
// 2删除数据
set.remove("小米");
System.out.println(set.toString());
// 3遍历
// 3.1增强for(set不能使用for,因为没有角标)
for (String s : set) {
System.out.println(s);
}
// 3.2使用迭代器
Iterator<String> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
// 4判断
System.out.println(set.contains("华为"));
System.out.println(set.isEmpty());
}