Typora+PicGo+阿里云OSS实现云笔记|Typora上传图片https://www.bilibili.com/video/BV1ci4y1L7j8/?spm_id_from=333.337.search-card.all.click&vd_source=3ae7423da4f44e42aa16cee6872b544f

常用快捷键

批量重命名:shift+F6

Lambda表达式(jdk8开始)

lambda表达式概述

1.为了简化匿名内部类的代码的写法
2.语法格式
1
2
3
4
(匿名内部类被重写方法的形参列表)->{
被重写的方法体代码
}
注意:->是语法形式,无实际含义
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
public class Test {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
public void run() {
System.out.println("跑起来");
}
};
animal.run();

Food food = new Food() {
@Override
public void eat() {
System.out.println("吃东西");
}
};
food.eat();
}
}

abstract class Animal{
public abstract void run();
}

interface Food{
void eat();
}

输出结果

1
2
跑起来
吃东西

实现demo

1
2
3
4
5
//lambdab表达式
Food food1 = ()->{
System.out.println("hahaha");
};
food1.eat();

注意:lambda表达式只能实现函数式接口,也就是只有一个抽象方法接口

Lambda表达式的省略规则

1.参数类型可以省略不写,

2.如果只有一个参数,参数类型可以省略不写,同可以()也可以省略

3.如果Lambda表达式的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!

4.在3的条件下,此时,如果这行代码是return语句,必须省略return不写,同时也必须省略分号

集合

合集的相关问题

1.数组和集合的元素存储的个数问题

  • 数组定义后类型确定,长度固定
  • 集合类型可以不固定,大小是可变的

2.数据和集合存储元素的类型问题

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

3.数组和集合适合的场景

  • 数组适合做数据个数和类型确定的场景
  • 集合适合做数据个数不确定,且要做增删元素的场景

集合类体系结构

集合分为Collection(单列)和Map(双列)

Collection:表示的每个元素只包含一个值

Map:每个元素包含两个值(键值对)

Collection集合体系

image-20230118175104874

泛型

集合都是泛型的形式,可以在编译阶段约束集合只能操作某种数据类型

格式:

1
2
3
Collection<String> lists = new ArrayList<>();
//省略写法
Collection<String> lists = new ArrayList()

注意:集合和泛型都只能支持引用数据类型,不支持基本数据类型,所以集合中存储的元素都以为是对象

如果集合中要存储基本类型的数据怎么办?

1
2
3
//存储基本类型包装类
Collection<Integer> lists = new ArrayList<>();
Collection<Double> lists = new ArrayList<>();

Collection集合常用的API

注意:Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用

方法名称 说明
public boolean add(E e) 把给定对象添加到当前集合中
public void clear() 清空集合中所有的元素
public void remove(E e) 把给定的对象在当前集合中删除
public boolean contains(Object obj) 判断当前集合是否包含给定的对象
public boolean isEmpty() 判断当前集合是否为空
public int size() 返回集合中元素的个数
public Object[] toArray() 把集合中元素,存储到数组中

迭代器遍历概述

迭代器在java中的代表是Iterator,迭代器是集合的专用的遍历方式

如何获取迭代器?
方法名称 说明
Iterator iterator() 返回集合中迭代器对象,该迭代器对象默认指向当前集合的0索引
Iterator中的常用方法
方法名称 说明
boolean hasnext() 询问当前位置是否有元素存在,存在返回true,不存在返回false
E next() 获取当前的位置的元素,并同时将迭代器对象移向下一个元素。

demo

1
2
3
4
5
6
7
8
9
ArrayList<Object> list= new ArrayList<>();
list.add("good");
list.add("good");
list.add("good");

Iterator<Object> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}

增强for

语法格式

1
2
3
for(元素数据类型 变量名 :数组或者Collection){
使用变量名即可
}
1
2
3
for (Object o : list) {
System.out.println(o);
}
Lambda表达式遍历集合
方法名称 说明
default void foreach(Consumer<? super T> action) 结合lambda遍历集合
1
2
3
4
5
6
7
System.out.println("======");
list.forEach(new Consumer<Object>() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});

简化版

1
list.forEach(o->System.out.println(o));

极限简化版

1
2
list.forEach(System.out::println);
//快捷方式,在foreach内输入sout即可

List集合特有的方法

方法名称 说明
void add(int index ,E element) 在集合的指定位置插入元素
E remve(int index) 根据索引删除元素,返回被删除的元素
E set (int index , E element) 修改指定索引处的元素,返回被修改的元素
E get (int index) 返回指定索引处的元素

总结:List 系列集合的特点

ArrayList,LinkedList:有序,可重复,有索引

List的实现类的底层原理

ArrayList底层是基于数组实现的,查询块,增删相对慢

LinkedList底层是基于双链表实现的,查询元素慢,增删首位元素非常快

LinkedList集合特有的方法

方法名称 说明
public void addFirst(E e) 在该列表开头插入元素
public void addLast(E e) 将指定的元素追加到此列表的末尾
public E getFirst() 获得集合中的第一个元素
public E getLast() 获得集合中的最后一个元素
public E removeFirst() 删除一个元素并返回第一个元素
public E removeLast() 删除最后一个元素并返回最后一个元素

集合的并发修改异常

从集合中的一批元素中找到某些元素并啥就拿出,如何操作?

错误demo:使用迭代器进行遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ArrayList<Object> list= new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");

//一个迭代器对象
Iterator<Object> iterator = list.iterator();

while(iterator.hasNext()){
Object next = iterator.next();
if(next=="1"){
list.remove(next);
}
}

报错信息:

image-20230119111610747

同样的如果使用foreach删除,或者lambda表达式进行删除也会报错

1
2
3
4
5
6
7
8
 		for (Object o : list) {
list.remove(o);
}

list.forEach(o->{
list.remove(o);
});
//这两种方式都会报错

改进方法:不使用集合对象去掉remove,而使用迭代器对象去remove

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 ArrayList<Object> list= new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");

//一个迭代器对象
Iterator<Object> iterator = list.iterator();

while(iterator.hasNext()){
Object next = iterator.next();
if(next=="1"){
// list.remove(next);
iterator.remove();
}
}

Collections排序相关的API

  • 使用范围:只能对List集合的排序

排序方式1:

方法名称 说明
public static void sort(List list) 将集合中元素按照默认的规则排序

排序方式2:

方法名称 说明
public static void sort(List list,Comparator c) 实现Comperator接口

demo

1
2
3
4
5
6
7
8
9
//通过sort来进行排序
Collections.sort(list);
System.out.println(list);
//通过实现list的Comparator方法,来自定义排序
Collections.sort(list, ( o1, o2)-> {
return o2-o1;
}
);
System.out.println(list);

Map集合体系

  • 是一种双列集合,每个元素包含两个元素
  • 每个元素的格式:key = value(键值对元素)
  • 也被称为”键值对集合“

Map集合整体格式

  • [key1 = value1,key2 = value2,….]

Map集合体系

image-20230122112758368

说明:

  • 使用最多的是Map集合是HashMap

特点:

  • Map集合的特点都是由键决定的
  • Map集合的键是无序的,不重复的,无索引的,值可以重复
  • Map集合后面重复的键对应的值会覆盖前面重复键的值
  • Map集合的键值对都可以为null

Map集合实现类的特点

  • HashMap:元素按照键是无序,不重复,无索引,值不做要求
  • LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求
  • TreeMap:元素按照键是排序,不重复,无索引,值不做要求

demo

1
2
3
4
5
6
7
8
9
// 1、创建一个Map集合对象
// Map<String, Integer> maps = new HashMap<>(); // 一行经典代码
Map<String, Integer> maps = new LinkedHashMap<>();
maps.put("鸿星尔克", 3);
maps.put("Java", 1);
maps.put("枸杞", 100);
maps.put("Java", 100); // 覆盖前面的数据
maps.put(null, null);
System.out.println(maps);

Map集合常用的API

  • Map是双列集合的祖宗接口,它的功能是全部双列集合都可以继承使用
方法名称 说明
v put(key,v value) 添加元素
v remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数

demo

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
  // 1.添加元素: 无序,不重复,无索引。
Map<String , Integer> maps = new HashMap<>();
maps.put("iphoneX",10);
maps.put("娃娃",20);
maps.put("iphoneX",100);// Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
maps.put("huawei",100);
maps.put("生活用品",10);
maps.put("手表",10);
// {huawei=100, 手表=10, 生活用品=10, iphoneX=100, 娃娃=20}
System.out.println(maps);

// 2.清空集合
// maps.clear();
// System.out.println(maps);

// 3.判断集合是否为空,为空返回true ,反之!
System.out.println(maps.isEmpty());

// 4.根据键获取对应值:public V get(Object key)
Integer key = maps.get("huawei");
System.out.println(key);
System.out.println(maps.get("生活用品")); // 10
System.out.println(maps.get("生活用品2")); // null

// 5.根据键删除整个元素。(删除键会返回键的值)
System.out.println(maps.remove("iphoneX"));
System.out.println(maps);

// 6.判断是否包含某个键 ,包含返回true ,反之
System.out.println(maps.containsKey("娃娃")); // true
System.out.println(maps.containsKey("娃娃2")); // false
System.out.println(maps.containsKey("iphoneX")); // false

// 7.判断是否包含某个值。
System.out.println(maps.containsValue(100)); //
System.out.println(maps.containsValue(10)); //
System.out.println(maps.containsValue(22)); //

// {huawei=100, 手表=10, 生活用品=10, 娃娃=20}
// 8.获取全部键的集合:public Set<K> keySet()
Set<String> keys = maps.keySet();
System.out.println(keys);

System.out.println("------------------------------");
// 9.获取全部值的集合:Collection<V> values();
Collection<Integer> values = maps.values();
System.out.println(values);

// 10.集合的大小
System.out.println(maps.size()); // 4

// 11.合并其他Map集合。(拓展)
Map<String , Integer> map1 = new HashMap<>();
map1.put("java1", 1);
map1.put("java2", 100);
Map<String , Integer> map2 = new HashMap<>();
map2.put("java2", 1);
map2.put("java3", 100);
map1.putAll(map2); // 把集合map2的元素拷贝一份到map1中去
System.out.println(map1);
System.out.println(map2);

Map集合的遍历方式一:键找值

  • 先获取Map集合的全部键的Set集合
  • 遍历键的Set集合,然后通过键提取对应的值

键找值涉及到的api

方法名称 说明
Set keySet() 获取所有的键的集合
V get(Object key) 根据键获取值

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
maps.put("iphoneX",10);
maps.put("娃娃",20);
maps.put("iphoneX",100);// Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
maps.put("huawei",100);
maps.put("生活用品",10);
maps.put("手表",10);
// {huawei=100, 手表=10, 生活用品=10, iphoneX=100, 娃娃=20}
// System.out.println(maps);
Set<String> strings = maps.keySet();
for (String string : strings) {
Integer integer = maps.get(string);
System.out.println(string+"="+integer);
}
}

Map集合的遍历方式二:键值对

  • 先把Map集合转成Set集合,Set集中每个元素都是键值对实体类型了
  • 遍历Set集合,然后提取键和值

键值对涉及到的api:

方法名称 说明
Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
K getKey() 获得键
V getValue() 获得值

demo

1
2
3
4
5
6
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"==="+value);
}

Map集合的遍历方式三:Lambda

方法名称 说明
default void forEach(BiComsumer<> action) 遍历Map集合

demo

1
2
3
4
5
6
maps.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
System.out.println(s+"===>"+integer);
}
});

Map集合的简单应用

统计100个人的投票情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
String[] choose = {"A","B","C","D","E"};
StringBuffer stringBuffer = new StringBuffer();
Random random = new Random();
for (int i = 0; i <100 ; i++) {
stringBuffer.append(choose[random.nextInt(choose.length)]);
}
System.out.println(stringBuffer);

HashMap<Character, Integer> hashMap = new HashMap<>();
for (int i = 0; i <stringBuffer.length() ; i++) {
char c = stringBuffer.charAt(i);
if(hashMap.containsKey(c)){
hashMap.put(c,hashMap.get(c)+1);
}else{
hashMap.put(c,1);
}
}
System.out.println(hashMap);

输出结果

1
{A=18, B=19, C=23, D=18, E=22}

HashMap的特点和底层原理

  • 由键决定:无序,不重复,无索引。HashMap底层是哈希表结构的。
  • 依赖hashCode方法和equals方法保证键的唯一
  • 如果键要存储的是自定义对象,需要重写hashCode和equals方法
  • 基于哈希表,增删改查的性能都比较好

嵌套集合demo

折叠文本 此处可书写文本 嗯,是可以书写文本的
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
package com.itheima.d9_map_impl;

import java.util.*;

/**
需求:统计投票人数
*/
public class MapTest4 {
public static void main(String[] args) {
// 1、要求程序记录每个学生选择的情况。
// 使用一个Map集合存储。
Map<String, List<String>> data = new HashMap<>();

// 2、把学生选择的数据存入进去。
List<String> selects = new ArrayList<>();
Collections.addAll(selects, "A", "C");
data.put("罗勇", selects);

List<String> selects1 = new ArrayList<>();
Collections.addAll(selects1, "B", "C" , "D");
data.put("胡涛", selects1);

List<String> selects2 = new ArrayList<>();
Collections.addAll(selects2 , "A", "B", "C" , "D");
data.put("刘军", selects2);

System.out.println(data);

// 3、统计每个景点选择的人数。
Map<String, Integer> infos = new HashMap<>(); // {}

// 4、提取所有人选择的景点的信息。
Collection<List<String>> values = data.values();
System.out.println(values);
// values = [[A, B, C, D], [B, C, D], [A, C]]
// value

for (List<String> value : values) {
for (String s : value) {
// 有没有包含这个景点
if(infos.containsKey(s)){
infos.put(s, infos.get(s) + 1);
}else {
infos.put(s , 1);
}
}
}

System.out.println(infos);
}
}

泛型的深入

泛型的概述和优势

泛型:是jdk5中引入的特性,可以在编译阶段约束操作的数据类型,并并进行检查

泛型的格式:<数据类型>;注意:泛型只能支持引用数据类型

泛型的好处:

统一数据类型。

把运行时期的问题提前到编译期间,避免了强制类型转换可能出现的异常,因为编译阶段类型就能确实下来

泛型可以在很多地方进行定义:

类的后面->泛型类

方法上声明->泛型方法

接口后面->泛型接口

后面再看05、泛型深入、自定义泛型、泛型通配符、上下限.mp4

Set系列集合

特点:
  • 无序:存取顺序不一致。

  • 不重复:可以去重复

  • 无索引:没有索引的方法,所以不能使用普通for循环遍历,也不能通过缩影来获取元素

Set集合实现类特点
  • HashSet:无序,,不重复,无索引

  • LinkedHashSet:有序,不重复,无索引

  • TresSet:排序,不重复,无索引

测试不重复的demo
1
2
3
4
5
HashSet<Object> objects = new HashSet<>();
objects.add("123");
objects.add("123");
objects.add("123");
System.out.println(objects);

输出结果:

1
[123]
HashSet底层原理
  • HashSet集合底层采取哈希表存储的数据结构
  • 哈希表是一种对于增删改查数据性能都比较号的结构
哈希表的构成

JDK8之前,底层使用数组+链表组成

JDK8之后,底层使用数组+链表+红黑树组成

哈希值
  • 是JDK根据对象的地址,按照某种规则算出来的int类型的数值
如何获取哈希值?

public int hashCode();返回对象的哈希值

对象的哈希值特点?
  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
  • 默认情况下,不同对象的哈希值是不同的

demo

1
2
String name = "zhangsan";
System.out.println(name.hashCode());

输出结果:

1
-1432604556
HashSet1.7版本原理解析:数组+链表+(结合哈希算法)
  1. 创建一个默认长度为16的数组,数组名为table
  2. 根据元素的哈希值跟数组的长度求余计算出应存入的位置
  3. 判断当前位置是否为null,如果null直接存入
  4. 如果位置不为null,且不一样,则调用equals方法比较
  5. 如果一样,则不存,如果不一样,则存入元素
  • JDK7新元素占老元素位置,指向老元素
  • JDK8新元素挂在老元素下面
HashSet1.8版本原理解析
  • 底层结构:数组,链表+红黑树结合体
  • 当挂在元素下面的数据过多是,查询性能降低,从JDK8开始之后,当链表长度超过8的时候,自动转换为红黑树
哈希表的详细流程
  • 创建一个默认长度为16的数组,数组名为table
  • 根据元素的哈希值和数组的长度计算出应存入的位置
  • 判断当前位置是否为null,如果为null,直接存入,如果不为null,表示有数据,则调用equals方法比较属性值,如果一样,则不存,如果不一样则入存入数组
  • 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍
如果利用hashSet去除重复的实体类对象

主要是要重写:Object的hashCode和equals

demo

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
public class Test {
public static void main(String[] args) {
HashSet<Student> set = new HashSet<>();
Student zhangsan = new Student("zhangsan", "11");
Student zhangsan2= new Student("zhangsan", "11");

set.add(zhangsan);
set.add(zhangsan2);
System.out.println(set);
}
}

class Student{
private String name;
private String age;

public Student() {
}

public Student(String name, String age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name) && Objects.equals(age, student.age);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
1
输出结果:[Student{name='zhangsan', age='11'}]
LinkedHashSet集合概述和特点
  • 有序,不重复,无索引
  • 这里的有序是指保存存储和取出的元素顺序一致
  • 原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序
TreeSet集合概述和特点
  • 不重复,无索引,可排序
  • 可排序:按照元素的大小默认升序(由小到大)排序
  • TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好

注意:TreeSet集合是一定要进行排序的,可以将元素按照指定的规制进行排序

默认的排序规则:

  • 对于数值类型:升序
  • 字符串类型:首字符的编号升序排序
  • 自定义类型:无法直接排序
自定义排序规则(treeSet)

方式一

  • 让自定义的类实现Comparable接口重写里面的compareTo方法来制定比较规则

核心代码部分:

1
2
class Student implements Comparable<Student>
//实现Comparable接口,并填写先对应的泛型

重写compareTo方法

1
2
3
4
5
@Override
public int compareTo(Student o) {
return this.age-o.age>=0 ? 1:-1;
}
//如果前面一个数大于或者等于后面一个数,那么返回1,反之返回-1

输出结果:

1
2
[Student{age=2}, Student{age=21}, Student{age=22}, Student{age=25}]

方式二

TresSet集合有有参构造器,可以设置Comparator接口对应的比较器对象,来指定比较规则

1
2
3
4
5
6
7
8
9
TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();//升序
return Double.compare(o1.getweight-o2.getweight)//浮点数据类型进行比较
}
});


可变参数

  • 可变参数用在形参中可以接受多个数据
  • 可变参数的参数:数据类型…参数名称
可变参数的作用
  • 传输参数非常灵活,方便。可以不传递参数,可以传递1个或者多个,也可以传输一个数组
  • 可变参数在方法内部本质上就是一个数组

可变参数的注意事项

  • 一个形参列表中可变参数只能有一个
  • 可变参数必须放在形参列表后面

Collections集合工具类

  • java.utils.Collections:是集合工具类
  • 作用:Collections并不属于集合,是用来操作集合的工具类

Collections常用的API

方法名称 说明
public static boolean addAll 给集合对象批量添加元素
public static void shuffle(List<?> list) 打乱List集合元素的顺序

demo

1
2
3
4
5
6
7
ArrayList<Integer> list = new ArrayList<>();
//通过addAll批量添加元素
Collections.addAll(list,1,2,3,4,5);
System.out.println(list);
//通过shufflet打乱集合的顺序
Collections.shuffle(list);
System.out.println(list);

创建不可变集合

什么是不可变集合?

  • 就是不可以被修改的集合
  • 集合的数据项再创建的时候提供,并且在整个生命周期里面,都不可以被修改

为什么要创建不可变集合?

重要数据,且不能修改

如何创建不可变集合?

在List、Set、Map接口中,都存在of方法,可以创建一个不可变的集合

demo

1
List<Integer> integers = List.of(1, 2, 3, 4, 5);

Stream流?

什么是Stream流?

在java8中,得益于Lambda所带来得函数式编程,引入了一个全新得Stream流概念

目的:用于简化集合和数组操作的api

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"123","12","1234");
// System.out.println(list);
//去除123开头的数字
ArrayList<Object> list1 = new ArrayList<>();
for (String s : list) {
if(s.startsWith("123")){
list1.add(s);
}
}
// System.out.println(list1);

//使用Stream流的方式进行完成
list.stream().filter(s -> s.startsWith("123")).forEach(System.out::println);
}

各种存储数据的容器添加集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/** --------------------Collection集合获取流-------------------------------   */
Collection<String> list = new ArrayList<>();
Stream<String> s = list.stream();

/** --------------------Map集合获取流------------------------------- */
Map<String, Integer> maps = new HashMap<>();
// 键流
Stream<String> keyStream = maps.keySet().stream();
// 值流
Stream<Integer> valueStream = maps.values().stream();
// 键值对流(拿整体)
Stream<Map.Entry<String,Integer>> keyAndValueStream = maps.entrySet().stream();

/** ---------------------数组获取流------------------------------ */
String[] names = {"赵敏","小昭","灭绝","周芷若"};
Stream<String> nameStream = Arrays.stream(names);
Stream<String> nameStream2 = Stream.of(names);

没看完,之后再看:02、Stream流体系.mp4

异常处理

什么是异常?

异常是程序在“编译”或者”执行”的过程中可能出现的问题,注意:语法错误不算在异常体系中。

日志框架