Object类
- 每个类都使用Oject作为父类,都可以使用其中的方法
toString
- 直接打印对象的名字,就是调用对象的
toString方法
String s = p1.toString();
System.out.println(s);
System.out.println(p1);
- 重写
toString方法,输出其中的变量成员
//重写toString方法
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
equals
- 默认的方法是比较值
public boolean equals(Object obj) {
return (this == obj);
}
- 重写比较对象的属性
@Override
public boolean equals(Object o) {
if (this == o) return true;
//getClass()获取类,使用反射技术
if (o == null || getClass() != o.getClass()) return false;
//向下转型
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
Objects
- 防止空指针异常
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
String s1 = "abc";
String s2 = "cbv";
System.out.println(Objects.equals(s1, s2));
Date
- 表示特定的瞬间,精确到毫秒
- 一个时间点,一刹那时间
- 可以对时间和日期进行计算
- 当前系统时间到1970年1月1日 00:00:00(英国格林威治时间)经历了多少毫秒,返回
long类型
System.out.println(System.currentTimeMillis());
- 系统的时间日期
Date d = new Date();
System.out.println(d);
- 将毫秒准换为时间日期
Date d1 = new Date(1627076830000L);
System.out.println(d1);
- 将日期转换为毫秒
Long time = d.getTime();
System.out.println(time);
DateFormat
- 时间日期格式化
- 抽象类,无法直接使用,需要使用
SimpleDateFormat - 日期转为字符串
//年月日-时分秒
String dateFormatStr = "yyyy.MM.dd - HH:mm:ss";
SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
System.out.println(dateFormat.format(d));
- 字符串转为日期
- parse声明了异常,如果字符串和格式不一样,程序会抛出异常,要么throw;要么try catch
public static void main(String[] args) throws ParseException {
//年月日-时分秒
String dateFormatStr = "yyyy.MM.dd - HH:mm:ss";
SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
System.out.println(dateFormat.parse("2014.5.6 - 23:55:23"));
}
Calendar
- 日历
- 月少一个,国外7月,国内8月;星期多一天,国外2,国内1
- 抽象类,通过静态方法获取对象
Calendar c= Calendar.getInstance();
- 通过字段获取具体的值
System.out.println(c.get(Calendar.DAY_OF_WEEK));
- 设置字段的值
c.set(Calendar.YEAR, 2010);
//同时设置年月日
c.set(2011,3,7);
- 修改指定的字段的值
c.add(Calendar.YEAR,-2);
- 转换成
Date形式
System.out.println(c.getTime());
System
- 返回当前时间的毫秒
System.out.println(System.currentTimeMillis());
- 数组复制,将src数组从第0个起,复制到dest数组第0个起的3个元素
System.arraycopy(src,0,dest,0,3);
System.out.println(Arrays.toString(dest));
StringBuilder
- 字符串缓冲区,提高字符串的操作效率
- 长度可以变化的字符串,底层也是一个数组,但是没有被
final修饰 - 底层初始长度为16,并且会自动扩容
- 构造,将
String转换成stringBuilder
StringBuilder stringBuilder = new StringBuilder();
System.out.println(stringBuilder);
StringBuffer stringBuffer2 = new StringBuffer("abc");
System.out.println(stringBuffer2);
- 添加任意类型数据的字符串,返回当前对象自身,返回的是this,所以无需接收返回值
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abc");
stringBuilder.append(true);
stringBuilder.append('c');
stringBuilder.append(9.6);
System.out.println(stringBuilder.append(100L));
//链式编程,方法的返回值是一个对象
stringBuilder.append("ab").append(false).append('b').append(9.8);
- toString,将
StringBuilder转换成String
System.out.println(stringBuilder.toString());
包装类
- 基本数据类型,没有方法操作这些数据
- 通过一个类,把基本数据类型包装起来,用类中的方法操作数据
- 装箱,把基本数据类型转换成包装类
//被移除
Integer integer1 = new Integer(8);
System.out.println(integer1);
Integer integer2 = new Integer("1");
System.out.println(integer2);
//静态方法
Integer integer3 = Integer.valueOf(8);
System.out.println(integer3);
Integer integer4 = Integer.valueOf("10");
System.out.println(integer4);
- 拆箱,包装类转换成基本数据类型
int i = integer4.intValue();
System.out.println(i);
- 包装类和基本数据类型会自动相互转换
- 基本数据类型和字符串类型的相互转换
//基本数据类型->String
String s1 = 8 + "";
System.out.println(s1+200);
String s2 = Integer.valueOf(89).toString();
System.out.println(s2+200);
String s3 = String.valueOf(11);
System.out.println(s3+200);
//String->基本数据类型
int i = Integer.parseInt(s3);
System.out.println(i + 200);
Collection
-
定义所有单列集合的共性的方法,没有带索引的方法 | Collection | | | :---: | :---: | | List接口 | Set接口 | | Vector | TreeSet | | ArrayList | HashSet | | LinkedList | LinkedHashSet(继承HashSet) |
-
添加元素
Collection<String> coll = new ArrayList<>();
coll.add("xiaoming");
coll.add("zhangsan"); // 一般返回都是true
coll.add("lisi");
coll.add("wangwu");
coll.add("zhaoliu");
coll.add("chenqi");
System.out.println(coll.toString());
- 删除
//删除成功返回true,不存在返回false
coll.remove("xiaoming");
- 是否包含某个元素
boolean res = coll.contains("lisi");
System.out.println(res);
- 是否为空
boolean empty = coll.isEmpty();
System.out.println(empty);
- 长度
int size = coll.size();
System.out.println(size);
- 转换成数组
Object[] arr = coll.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
- 清空所有集合
coll.clear();
System.out.println(coll.toString());
System.out.println(coll.isEmpty());
List接口
- 有序
- 允许存储重复的元素
- 有索引,可以用普通的for循环遍历
- 在指定索引处添加方法
list.add(3,"xiaoming");
- 移除元素,并返回被移除的内容
String removeStr = list.remove(2);
- 替换元素,并返回被替换的内容
String setStr = list.set(1, "zhangsan");
- 遍历方法,
get获取
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("------------------");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("------------------");
for (String s : list) {
System.out.println(s);
}
ArrayList
- 底层数据结构是数组结构,实现是多线程的
- 如果要添加元素,要创建新数组,数组长度+1
- 查询比较多,可以使用
add(int idx, int element)将原有idx的元素往后推set(int idx, int element)修改idx的元素
LinkedList
- 不能使用多态创建,不能使用其中的子类方法
- 链表结构,多线程,查询慢,增删快
- 添加头尾
list.addFirst("xiaoming");
//效果跟addFirst一致
list.push("wangwu");
list.addLast("zhangsan");
System.out.println(list);
- 获取头尾
String getFirstStr = list.getFirst();
String getLastStr = list.getLast();
System.out.println(getFirstStr);
System.out.println(getLastStr);
- 删除头尾,返回删除的内容
String removeFirstStr = list.removeFirst();
//与removeFirst效果一致
String popStr = list.pop();
String removeLastStr = list.removeLast();
System.out.println(removeFirstStr);
System.out.println(removeLastStr);
System.out.println(popStr);
- 队列使用
Queue<String> strings = new LinkedList<>();
//添加元素,添加失败返回false
strings.offer("zhangsan");
strings.offer("lisi");
strings.offer("wangwu");
//看第一个元素,不存在返回null
String peek = strings.peek();
System.out.println(peek);
//返回第一个元素,并从队列中删除,不存在返回null
String poll = strings.poll();
System.out.println(poll);
Vector
- 底层是数组,单线程
Set接口
- 不允许存储重复元素
- 没有索引
- HashSet是无序的,存取元素的顺序可能不一致
HashSet
- 不保证迭代的顺序,不保证顺序恒久不变,多线程
- 底层是哈希表结构,查询速度非常快
- 不允许存储相同内容的原理,Set集合在调用
add的时候,会调用hasCode和equals方法,判断元素是否重复;存储的元素必须重写hasCode和equals方法
HashSet<String> set = new HashSet<>();
String s1 = new String("abc");
String s2 = new String("abc");
set.add(s1);
set.add(s2);
set.add("重地");
set.add("通话");
set.add("abc");
System.out.println("abc".hashCode());
System.out.println(set);
LinkedHashSet
- 底层是哈希表+链表,多了一条链表记录元素存储顺序,保证元素有序
TreeSet
- 非同步,底层是二叉树(红黑树),性能没有hashset好,不允许有null,有序
哈希值
- 十进制的整数,由系统随机给出,是对象的地址值,是一个逻辑地址,模拟的出来的地址,并不是数据实际存储的物理地址
- 获取哈希值
Person p = new Person();
System.out.println(p);
System.out.println(p.hashCode());
//输出,toString方法输出的地址值,就是哈希值的十六进制形式
com.mzx.java.DemoList.DemoSet.Person@4617c264
1175962212
- 字符串类的哈希值
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
//输出,字符串一样,输出的哈希值一样,重写了hasCode方法
96354
96354
哈希表
- 1.8前 数组+链表
- 1.8后 数组+红黑树
- 查询速度快
- 数据结构:把元素进行分组,存储哈希值
- 链表/红黑树结构,把相同哈希值连接到一起,如果某个数组下面的元素长度超过8个,用红黑树结构
Iterator
- 迭代器
Iterator interator = coll.iterator();
//是否有下一个元素
boolean res = interator.hasNext();
System.out.println(res);
//取出下一个
System.out.println(interator.next());
- 循环取出
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println(iterator.hasNext());
}
实现原理
- 实现类对象,指针指向集合的-1索引
- next()取出下一个元素,指针向后移动一位
增强for循环
- 底层也是迭代器
- 所有单列集合都可以使用
- 被遍历的目标只能是集合或者数组
for (String str : coll) {
System.out.println(str);
}
数据结构
栈
- 先进后出
- 入口出口在一侧
队列
- 先进先出
数组
- 查询快,增删慢
- 有序,有索引
- 数组地址是连续的,通过数组的首地址可以找到数组,通过索引快速查找某一个元素
- 数组的长度是固定的,增删必须创建一个新数组,把源数组的数据复制过来,将新数组的地址赋值给变量,源数组会在内存中被销毁
- 在堆内存中,频繁地创建数组,复制数组中的元素,销毁数组,效率低下
链表
-
查询慢,增删快
-
链表中的地址不是连续的,每次查询元素,都要从头开始查询
-
链表借口,增删元素,对链表的整体结构没有影响
-
链表中的每一个元素称之为节点,一个节点包含了一个数据域(存储数据),两个指针域(存储地址) | 自己的地址 | 数据 | 下一个节点的地址 | |:----:|:----:|:----:|
-
单向链表,只有一条链子,不能保证元素的顺序,存取顺序有可能不一致
-
双向链表,有两条链子,有一条链子专门记录元素的顺序,有序
-
第一条链记录本节点和下一个节点的地址,不保证顺序;第二条链记录顺序
树
- 二叉树,分支不能超过两个,左(右)孩子(子树)
- 平衡树,左子树的数量和右子树的数量相等
- 不平衡树,左子树的数量和右子树的数量不相等
排序树(查找树)
- 在二叉树的基础上,元素上有大小顺序,左子树小,右子树大
- 左子树的所有节点都比根节点小
- 右子树的所有节点都比根节点大
- 左子树小于节点,右子树要大于节点
红黑树
- 趋近于平衡树,查询速度非常快,查询叶子节点最大次数和最小次数之比不能超过两倍
- 节点可以是红色的或者黑色的
- 根节点是黑色的
- 叶子节点(空节点,接下去没有子节点)是黑色的
- 每个红色的节点的子节点都是黑色的,不能有两个连续的红色节点
- 任何一个节点到其每一个叶子节点的所有路径上黑色的节点数相同
Collections
Collection的工具类- 添加多个元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"a","b","c","d","e","f");
- 打乱集合的顺序
Collections.shuffle(list);
- 排序,默认是升序,被排序的集合中的元素必须实现
Comparable,重写接口中的CompareTo定义排序的方式
Collections.sort(list);
System.out.println(list);
ArrayList<Person> list1 = new ArrayList<>();
list1.add(new Person("xiaoming",18));
list1.add(new Person("zhangsan",15));
list1.add(new Person("lisi",20));
System.out.println(list1);
Collections.sort(list1);
System.out.println(list1);
//重写
@Override
public int compareTo(Person o) {
//(this - 参数)返回值大于0,升序排序
return this.getAge() - o.getAge();
}
Comparable与Comparator
Comparable,自己(this)与别人(参数)进行比较,自己需要实现Comparable,重写接口中的CompareTo定义排序的方式Comparator,相当于找一个第三方的裁判,比较两个- 匿名内部类实现自定义的排序方法
ArrayList<Character> list = new ArrayList<>();
Collections.addAll(list,'a','b','c','d','e','f');
Collections.shuffle(list);
System.out.println(list);
Collections.sort(list, new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o2 - o1;
}
});
System.out.println(list);
ArrayList<Person> list1 = new ArrayList<>();
list1.add(new Person("xiaoming",18));
list1.add(new Person("zhangsan",15));
list1.add(new Person("lisi",20));
list1.add(new Person("wangwu",22));
list1.add(new Person("zhaoliu",20));
System.out.println(list1);
Collections.sort(list1, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int res = o2.getAge() - o1.getAge();
if (res == 0) {
res = o2.getName().charAt(0) - o1.getName().charAt(0);
}
return res;
}
});
System.out.println(list1);
泛型
- 当不知道需要使用什么数据类型的时候,使用泛型
- 不使用泛型,默认为
Object,可以存储任意类型的数据,但是不安全,引发异常 - 使用泛型,避免类型转换,把运行的异常提前到编译期(编写代码的时候)
- 字母无所谓
- E e,Element元素,未知的数据类型;创建集合对象的时候,就会确定泛型的数据类型
public E set(int index, E element) {
Objects.checkIndex(index, size);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
- T t,Type类型,
自定义泛型
- 类
public class GenericClass<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
- 含有泛型的方法
public <M> void method(M m) {
System.out.println(m);
}
//静态方法
public static <S> void methodStatic(S s) {
System.out.println("methodStatic - " + s);
}
//使用
gc.method("xiaoming");
gc.method(1);
gc.method(10.888);
GenericClass.methodStatic("zhangsan");
GenericClass.methodStatic(123.33);
GenericClass.methodStatic(true);
- 含有泛型的接口
//接口
public interface GenericInterface<I> {
void methodInterface(I i);
}
//第一种使用方式,直接在实现类中指定泛型类型
public class GenericInterfaceImpl implements GenericInterface<String>{
@Override
public void methodInterface(String s) {
System.out.println(s);
}
}
GenericInterfaceImpl gi = new GenericInterfaceImpl();
gi.methodInterface("zhangsan");
//第二种使用方式,创建对象时指定泛型
public class GenericInterfaceImpl<S> implements GenericInterface<S>{
@Override
public void methodInterface(S s) {
System.out.println(s);
}
}
GenericInterfaceImpl<Integer> gi = new GenericInterfaceImpl();
gi.methodInterface(1);
泛型通配符
<?>- 代表任意的数据类型,不能创建对象使用,只能作为方法的参数使用
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
ArrayList<String> list2 = new ArrayList<>();
list2.add("zhangsan");
list2.add("lisi");
printArray(list1);
printArray(list2);
public static void printArray(ArrayList<?> list) {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
受限泛型
- 上限,
? extneds E,代表泛型只能是E类型的子类/本身 - 下限,
? super E,代表泛型只能是E类型父类/本身
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement1(list1);
//list2不是Number的子类或者本身
getElement1(list2);//报错
getElement1(list3);
//list4不是Number的子类或者本身
getElement1(list4);//报错
//list1/2不是Number的父类或者本身
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
/*
类与类之间的继承关系
Integer extends Number extends Object
String extends Object
*/
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}
可变参数
- 传递的个数不确定,类型确定
- 底层就是一个数组,根据传递参数个数不同,创建不同长度的数据,用来存储这些参数
- 一个方法的参数列表,只能有一个可变参数
- 如果参数有多个,可变参数必须写在参数列表的末尾
/调用
System.out.println(add(1,2,3,4,5,6,7,8,9));
public static int add(int ... nums) {
int res = 0;
for (int i = 0; i < nums.length; i++) {
res += nums[i];
}
return res;
}
- 可变参数特殊写法
public static void print(Object ... o) {
for (Object o1 : o) {
System.out.println(o1);
}
}
Map
- Map<K, V>
- 将键映射到值
- 必须保证
Key唯一,作为Key的元素,必须重写hasCode和equals方法,保证Key唯一
HashMap
HashSet底层使用了HashMap的Key
public HashSet() {
map = new HashMap<>();
}
- 底层是哈希表,1.8前使用数组+单向链表;1.8后使用数组+单向链表/红黑树
- 无序集合
put添加元素,如果Key重复则返回被替代的元素,如果不存在返回null
Map<String, String> map = new HashMap<>();
String returnStr = map.put("zhangsan","zhangsan1");
System.out.println(returnStr);
returnStr = map.put("zhangsan","zhangsan2");
System.out.println(returnStr);
remove删除指定的Key,返回Value,不存在返回null
map.put("lisi","lisi2");
map.put("wangwu","wangwu2");
map.put("zhaoliu","zhaoliu2");
map.put("chenqi","chenqi2");
map.put("huangba","huangba2");
System.out.println(map);
System.out.println(map.remove("zhaoliu"));
System.out.println(map.remove("dd"));
System.out.println(map);
get获取value,没有返回null
System.out.println(map.get("www"));
System.out.println(map.get("wangwu"));
contains是否包含指定的Key或Value
System.out.println(map.containsKey("wangwu")); //true
System.out.println(map.containsKey("zhaooliu"));//false
System.out.println(map.containsValue("wangwu2"));//true
System.out.println(map.containsValue("wangwu"));//false
- 遍历
Set<String> kSet = map.keySet();
kSet.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s + " = " + map.get(s));
}
});
System.out.println("--------------");
for (String s : kSet) {
System.out.println(s + " = " + map.get(s));
}
- 存储自定义类型
Key为String,已经重写hasCode和equals方法
HashMap<String, Person> map = new HashMap<>();
map.put("beijing",new Person("zhangsan",18));
map.put("chongqing",new Person("lisi",23));
map.put("hangzhou",new Person("wangwu",12));
map.put("shanghai",new Person("zhaoliu",15));
map.put("shenzhen",new Person("chenqi",20));
for (Map.Entry<String, Person> stringPersonEntry : map.entrySet()) {
System.out.println(stringPersonEntry.getKey() + " = " + stringPersonEntry.getValue());
}
Key为Person,需要重写hasCode和equals方法
//重写
@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);
}
//使用
HashMap<Person, String> map2 = new HashMap<>();
map2.put(new Person("zhangsan",18),"beijing");
map2.put(new Person("lisi",23),"chongqing");
map2.put(new Person("wangwu",12),"hangzhou");
map2.put(new Person("zhaoliu",15),"shanghai");
map2.put(new Person("chenqi",20),"shenzhen");
map2.put(new Person("chenqi",20),"shenzhen");
map2.put(new Person("chenqi",20),"shenzhen");
for (Map.Entry<Person, String> stringPersonEntry : map2.entrySet()) {
System.out.println(stringPersonEntry.getKey() + " = " + stringPersonEntry.getValue());
}
Entry
Map的内部接口- 用来记录键与值,键值对对象,键与值的映射关系
- 类似
Iterator遍历集合
Set<Map.Entry<String, String>> set = map.entrySet();
for (Map.Entry<String, String> s : set) {
System.out.println(s.getKey() + " = " + s.getValue());
}
LinkedHashMap
- 有序,不允许重复
- 哈希表+链表,保证迭代顺序
- 继承
HashMap
Map<String, String> hashMap = new HashMap<>();
hashMap.put("chenqi","chenqi2");
hashMap.put("huangba","huangba2");
hashMap.put("lisi","lisi2");
hashMap.put("wangwu","wangwu2");
hashMap.put("zhaoliu","zhaoliu2");
System.out.println(hashMap);
System.out.println("---------------");
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("chenqi","chenqi2");
linkedHashMap.put("huangba","huangba2");
linkedHashMap.put("lisi","lisi2");
linkedHashMap.put("wangwu","wangwu2");
linkedHashMap.put("zhaoliu","zhaoliu2");
System.out.println(linkedHashMap);
Hashtable
- 不允许存储空,是同步的,单线程
- 被取代
- 子类
Properties仍在使用,唯一一个和IO流相结合的集合
TreeMap
- 加入后有序,默认升序
- 基本使用
TreeMap<Integer, Integer> map = new TreeMap<>();
map.put(10,32);
map.put(111,42);
map.put(20,12);
map.put(5,53);
//默认升序
//最小的key
System.out.println(map.firstKey());
//直接取出最小的key的键值对
System.out.println(map.pollFirstEntry());
//最大的key
System.out.println(map.lastKey());
//最大的key的键值对
System.out.println(map.lastEntry());
- 取顶和取底
TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(1, "xiaoming - " + 1);
treeMap.put(3, "xiaoming - " + 1);
treeMap.put(8, "xiaoming - " + 1);
treeMap.put(10, "xiaoming - " + 1);
Integer lowerKey = treeMap.lowerKey(10);
// 8 不包括10
System.out.println(lowerKey);
Integer floorKey = treeMap.floorKey(10);
// 10 包括10
System.out.println(floorKey);
Integer higherKey = treeMap.higherKey(3);
// 8 不包括3
System.out.println(higherKey);
Integer ceilingKey = treeMap.ceilingKey(3);
//3 包括3
System.out.println(ceilingKey);
- 设置降序
TreeMap<Integer, Integer> map = new TreeMap<>((o1, o2) -> o2 - o1);
- 自定义类,实现排序
//调用
TreeMap<Person, Integer> map = new TreeMap<>(new ComparatorPerson());
map.put(new Person("zhangsan",132),13);
map.put(new Person("zhangsan",1552),14);
map.put(new Person("zhangsan",12),12);
//实现接口
class ComparatorPerson implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.age - o2.age;
}
}
//或者key实现Comparable接口
class Person implements Comparable<Person>{
//其他代码...
@Override
public int compareTo(Person o) {
return o.age - this.age;
}
}
集合一次性添加多个元素
- 集合中存储的元素个性已经确定,在不改变时使用
of方法只适用于list、Set、Map- 返回的是一个不能改变的集合
Set和Map在调用of的时候,不能有重复的元素
List<? extends Serializable> list = List.of(1, 2, 4, "b");
System.out.println(list);
Set<String> set = Set.of("a", "b", "c");
System.out.println(set);
Map<Integer, String> map = Map.of(1, "xiaoming", 2, "lisi", 3, "wangwu");
System.out.println(map);