Java学习笔记 - Java8新特性

Lambda表达式

  • Lambda表达式是一个函数式接口的实例

语法

1
2
(o1,o2) -> Integer.compare(o1,o2);
Lambda形参列表 -> Lambda体// -> : Lambda操作符或者箭头操作符

使用情形

  • ->左边(形参列表):
    • Lambda形参列表只有一个参数时,可以省略()
    • Lambda形参列表没有或者两个以上参数,括号不可以省略
  • ->右边(Lambda体):
    • Lambda体应该使用一对{}包括
    • 如果只有一条执行语句(可能是return语句)可以省略{}
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
public class LambdaTest1 {
//语法格式1:无参,无返回值
@Test
public void test1(){
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
int compare = comparator.compare(12, 34);
System.out.println(compare);

//lambda表达式
Comparator<Integer> comparator1 = (o1, o2) -> Integer.compare(o1, o2);
int compare1 = comparator1.compare(38, 34);
System.out.println(compare1);
}


//语法表达式2:需要一个参数,但是没有返回值
@Test
public void test2(){
Consumer<String> con = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
con.accept("谎言和誓言的区别是什么?");

//lambda表达式
Consumer<String> con1 = (String s) -> System.out.println(s);
con1.accept("一个是听的人当真了,一个是说的人当真了");
}

//语法格式3:数据类型可以省略,可由编译器推断的出,称为“类型推断”
@Test
public void test3(){
Consumer<String> con1 = (String s) -> System.out.println(s);
con1.accept("一个是听的人当真了,一个是说的人当真了");

//改进
Consumer<String> con2 = (s) -> {
System.out.println(s);
};
con2.accept("一个是听的人当真了,一个是说的人当真了");
ArrayList<String> arrayList = new ArrayList<>();//类型推断
int[] arr = {1,2,3};//类型推断
}

//语法格式4:Lambda若只有一个参数时,参数的小括号可以省略
@Test
public void test4(){
Consumer<String> con1 = (s) -> {
System.out.println(s);
};
con1.accept("一个是听的人当真了,一个是说的人当真了");
//改进
Consumer<String> con2 = s -> {
System.out.println(s);
};
con2.accept("一个是听的人当真了,一个是说的人当真了");
}

//语法格式5:Lambda需要两个或以上的参数,多条执行语句,并且可以有返回值
@Test
public void test5(){
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
int compare = comparator.compare(12, 34);

//改进
Comparator<Integer> comparator1 = (o1,o2) -> {
System.out.println(o1);
System.out.println(o2);
return Integer.compare(o1,o2);
};
}

//语法格式6:当Lambda只有一条语句时,return 和 {}若有,都可以省略
@Test
public void test6(){
Comparator<Integer> comparator1 = (o1,o2) -> {
return Integer.compare(o1,o2);
};
}

//改进
Comparator<Integer> comparator1 = (o1,o2) -> Integer.compare(o1,o2);
}

函数式接口

  • 只包含一个抽象方法的接口,称为函数式接口

  • 在一个接口上使用@FunctionalInterface注解,可以检查它是否是一个函数式接口

java内置四大核心函数式接口

函数式接口 参数类型 返回类型 用途
Consumer 消费型接口 T void 对类型为T的对象应用操作,包含方法: void accept(T t)
Supplier 供给型接口 T 返回类型为T的对象,包含方法:T get()
Function 函数型接口 T R 对象类型为T的对象应用操作,并返回结果,结果是R类型的对象,包含方法:R apply(T t)
Predicate 断定型接口 T boolean 确定类型为T的对象是否满足某约束,并返回布尔值,包含方法:boolean test(T t)
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
public class LambdaTest2 {
//消费型接口
@Test
public void test1(){
//普通写法
consumer(1000, new Consumer<Double>() {
@Override
public void accept(Double aDouble) {
System.out.println("您共消费:" + aDouble);
}
});

//Lambda表达式写法
consumer(400, money -> System.out.println("您共消费:" + money))
}
public void consumer(double money, Consumer<Double> con){
con.accept(money);
}

@Test
//断定型接口
public void test2(){
List<String> arr = Arrays.asList("天津", "南京", "北京", "东京", "山海经");
//普通写法
List<String> list = findString(arr, new Predicate<String>() {
@Override
public boolean test(String s) {
return s.contains("京");
}
});
System.out.println(list);

//Lambda表达式写法
List<String> list1 = findString(arr, s -> s.contains("京"));
System.out.println(list1);
}

public List<String> findString(List<String> list, Predicate<String> pre) {
ArrayList<String> arrayList = new ArrayList<>();
for (String s : list) {
//pre.test(s) 为true
if (pre.test(s)) {
arrayList.add(s);
}
}
return arrayList;
}
}

其他接口

方法引用

语法

1
类(或对象) :: 方法名

使用要求

  • 实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致

使用情形

1
2
3
//对象 :: 实例方法名
//类 :: 静态方法名
//类 :: 实例方法名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
public class MethodReferences {

//情况1:对象 :: 实例方法
//消费型接口
//Consumer中的void accept(T t)
//PrintStream中的println(T t)
@Test
public void test1(){
//普通写法
Consumer<String> stringConsumer = new Consumer<String>(){
@Override
public void accept(String s) {
System.out.println(s);
}
};

//Lambda表达式写法
Consumer<String> con1 = s -> System.out.println(s);
con1.accept("南京");

//方法引用
PrintStream out = System.out;
Consumer<String> con2 = out :: println;
//Consumer<String> con2 = System.out :: println;
con2.accept("北京");
}

//供给型接口
//Supplier中的T get()
//Employee中的String getName()
@Test
public void test2(){

//普通写法
Employee tom = new Employee("Tom");
Supplier<String> s = new Supplier<String>() {
@Override
public String get() {
return tom.getName();
}
};
System.out.println(s.get());

//Lambda表达式
Supplier<String> s1 = () -> tom.getName();
System.out.println(s1.get());

//方法引用
Supplier<String> s2 = tom :: getName;
System.out.println(s2.get());
}

//情况2:类 :: 静态方法
//Comparator中的int compare(T t1, T t2)
//Integer中的int compare(T t1, T t2)
@Test
public void test3(){

//普通写法
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
System.out.println(com.compare(12,3));

//Lambda表达式
Comparator<Integer> com1 = (o1,o2) -> Integer.compare(o1,o2);
System.out.println(com1.compare(3,5));

//方法引用
Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(5,9));
}

//Function中的R apply(T t)
//Math中的Long round(Double d)
@Test
public void test4(){

//普通写法
Function<Double,Long> fun = new Function<Double, Long>() {
@Override
public Long apply(Double d) {
return Math.round(d);
}
};
System.out.println(fun.apply(15.63));

//Lambda表达式
Function<Double,Long> fun1 = d -> Math.round(d);
System.out.println(fun1.apply(55.3));

//方法引用
Function<Double,Long> fun2 = Math::round;
System.out.println(fun2.apply(42.6));

}

//情况3: 类 :: 实例方法
// Comparator中的int compare(T t1, T t2)
// String中的int t1.compareTo(t2)
@Test
public void test5(){
//Lambda表达式
Comparator<String> com = (s1,s2) -> s1.compareTo(s2);
System.out.println(com.compare("abc", "abd"));

//方法引用
Comparator<String> com1 = String :: compareTo;
System.out.println(com1.compare("adm", "abg"));
}

//BiPredicate中的boolean test(T t1, T t2)
//String中boolean t1.equals(t2)
@Test
public void test6(){
//普通写法
BiPredicate<String,String> pre = new BiPredicate<String, String>() {
@Override
public boolean test(String s1, String s2) {
return s1.equals(s2);
}
};
System.out.println(pre.test("abc", "abc"));

//Lambda表达式
BiPredicate<String,String> pre1 = (s1, s2) -> s1.equals(s2);
System.out.println(pre1.test("dbd", "abd"));

//方法引用
BiPredicate<String,String> pre2 = String :: equals;
System.out.println(pre2.test("abc", "abc"));
}

// Function中的R apply(T t)
// Employee中的String getName()
@Test
public void test7(){
Employee employee = new Employee("jack");

//普通写法
Function<Employee,String> fun = new Function<Employee, String>() {
@Override
public String apply(Employee e) {
return e.getName();
}
};

//Lambda表达式
Function<Employee,String> fun1 = e -> e.getName();
System.out.println(fun1.apply(employee));

//方法引用
Function<Employee,String> fun2 = Employee :: getName;
System.out.println(fun2.apply(employee));
}
}

构造器引用

  • 函数式接口的抽象方法的形参列表和构造器的形参列表一致,抽象方法的返回值类型即为构造器的类的类型
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
//构造器引用
//Supplier中的T get()
//Employee中的无参构造器 Employee()
@Test
public void test1(){

//普通写法
Supplier<Employee> sup = new Supplier<Employee>() {
@Override
public Employee get() {
return new Employee("may", 17);
}
};
System.out.println(sup.get());

//Lambda表达式
Supplier<Employee> sup1 = () -> new Employee("hello", 23);
System.out.println(sup1.get());

//构造器引用
Supplier<Employee> sup2 = Employee :: new;
System.out.println(sup2.get());

}

//Function中的R apply(T t)
@Test
public void test2(){
//Lambda表达式
Function<Integer, Employee> fun = (age) -> new Employee(age);
System.out.println(fun.apply(23));

//构造器引用
Function<Integer, Employee> fun1 = Employee :: new;
System.out.println(fun1.apply(36));
}

//BiFunction中的R apply(T t, U u)
@Test
public void test3(){
//Lambda表达式
BiFunction<Integer,String,Employee> bif = (age, name) -> new Employee(name,age);
System.out.println(bif.apply(26,"smith"));

//构造器引用
BiFunction<String,Integer,Employee> bif1 = Employee :: new;
System.out.println(bif1.apply("Tom", 39));
}

数组引用

  • 可将数组看成一个特殊的类,和构造器引用一致
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//数组引用
//Function中的R apply(T t)
@Test
public void test4(){
//普通写法
Function<Integer,String[]> fun = new Function<Integer, String[]>() {
@Override
public String[] apply(Integer integer) {
return new String[integer];
}
};
String[] arr = fun.apply(5);
System.out.println(Arrays.toString(arr));

//Lambda表达式
Function<Integer,String[]> fun1 = length -> new String[length];
System.out.println(Arrays.toString(fun1.apply(5)));

//数组引用
Function<Integer,String[]> fun2 = String[] ::new;
System.out.println(Arrays.toString(fun2.apply(5)));
}
}

Stream的API

创建Stream

  • 一个数据源(数组、集合),获取一个流

通过集合创建

1
2
default Stream<E> stream();//返回一个顺序流
default Stream<E> parallelStream();//返回一个并行流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//创建Stream方式一:通过集合
@Test
public void test1() {
List<String> list = new ArrayList<>();
list.add("三国演义");
list.add("水浒传");
list.add("西游记");
list.add("红楼梦");

// default Stream<E> stream() : 返回一个顺序流
Stream<String> stream = list.stream();

// default Stream<E> parallelStream() : 返回一个并行流
Stream<String> stringStream = list.parallelStream();
}

通过数组创建

1
static <T> Stream<T> stream(T[] array);//返回一个流
1
2
3
4
5
6
7
//创建Stream方式二:通过数组
@Test
public void test2(){
//调用Arrays类的static <T> Stream<T> stream(T[] array) : 返回一个流
int[] arr = {1,2,3,4};
IntStream stream = Arrays.stream(arr);
}

通过Stream的of()创建

1
2
3
4
5
//创建Stream方式三:通过stream的of()
@Test
public void test3(){
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
}

创建无限流

1
2
3
4
5
6
7
8
9
@Test
public void test4(){
//迭代
//public static<T> Stream<T> iterate(final T seed,final UnaryOperator<T> f)
Stream.iterate(0,t -> t + 2).limit(10).forEach(System.out::println);
//生成
//public static<T> Stream<T> generate(Supplier<T> s)
Stream.generate(Math :: random).limit(10).forEach(System.out::println);
}

中间操作

  • 一个中间操作链,对数据源的数据进处理

筛选与切片

1
2
3
4
filter(Predicate p);//接收Lambda,从流重排除某些元素
distinct();//筛选,通过流产生的元素的hashCode()和equals()去除重复的元素
limit(long maxSize);//截断流,使其元素不超过给定的值
skip(long n);//跳过元素,返回一个仍掉了前n个元素的流。若流中元素不足n个,则返回一个空流,与limit(n)互补
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//1. 筛选与切片
@Test
public void test1(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

//filter(Predicate p) -- 接收Lambda 从流中排除某些元素
Stream<Integer> stream = list.stream();
stream.filter(num -> num > 2).forEach(System.out::println);

//limit(n) -- 截断流,使其元素不超过给定数量
list.stream().limit(2).forEach(System.out::println);

//skip -- 跳过元素,返回一个去掉了前n个元素的流,若流中元素不足n个 ,则返回一个空流
list.stream().skip(2).forEach(System.out::println);

//distinct -- 筛选去重,通过流所生成元素的hashCode() 和equals() 去除重复元素
list.add(4);
System.out.println(list);
list.stream().distinct().forEach(System.out::println);
}

映射

1
2
3
4
5
map(Function f);//接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
map ToDouble(ToDoubleFunction f);//接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream
map Tolnt(TolntFunction f);//接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream
map ToLong(ToLongFunction f);//接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream
flatMap(Function f);//接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
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
//映射
@Test
public void test1() {
//map(Function f) -- 接收一个函数作为参数,将元素转换成其他形式或提取信息
// 该函数会被应用到每个元素上,并将其映射成一个新的元素
List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);

//获取Stream
Stream<Stream<Character>> streamStream = list.stream().map(str -> StreamAPITest3.formStringToStream(str));
streamStream.forEach(s -> {
s.forEach(System.out::println);
});
//flatMap(Function f) -- 接收一个函数作为参数,将流中的每个值都换成另外一个流,然后把所有的流 重新组成一个新的流

Stream<Character> characterStream = list.stream().flatMap(str -> StreamAPITest3.formStringToStream(str));
characterStream.forEach(System.out::println);
}

//将字符串中的多个字符构成的集合转换为对应的Stream的实例
public static Stream<Character> formStringToStream(String str) {//aa
ArrayList<Character> list = new ArrayList<>();
for (Character c : str.toCharArray()) {
//将获取的字符加入到集合
list.add(c);
}
return list.stream();
}

排序

1
2
3
4
5
6
7
8
9
10
11
12
//排序
@Test
public void test4() {
//sorted() -- 自然排序
List<Integer> list = Arrays.asList(1, 2, 5, -9, 34, 3);
list.stream().sorted().forEach(System.out::println);

//sorted() -- 定制排序
List<Employee> employeeData = EmployeeData.getEmployeeData();
employeeData.stream().sorted((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()))
.forEach(System.out::println);
}

终止操作

  • 一旦执行终止操作,就执行中间操作链,并产生结果,之后不会再被使用

匹配与查找

1
2
3
4
5
6
7
8
9
allMatch(Predicate p);//检查是否匹配所有元素
anyMatch(Predicate p);//检查是否至少匹配一个元素
noneMatch(Predicate p);//检查是否没有匹配所有元素
findFirst();//返回第一个元素
findAny();//返回当前流中的任意元素
count();//返回流中元素总数
max(Comparator c);//返回流中最大值
min(Comparator c);//返回流中最小值
forEach(Consumer c);//内部迭代(使用 Collection接口需要用户去做迭代,称为外部迭代。相反,Stream API使用内部迭代——它帮你把迭代做了)
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
@Test
public void test1(){
List<Employee> employeeData = EmployeeData.getEmployeeData();
// aLlMatch(Predicate p)—检查是否匹配所有元素。
// 练习:是否所有的员工的年龄都大于18
Stream<Integer> integerStream = employeeData.stream().map(Employee::getAge);
boolean allMatch = integerStream.allMatch(age -> age > 18);
System.out.println(allMatch);

// anyMatch(Predicate p)—检查是否至少匹配一个元素。
// 练习:是否存在员工的年龄小于18
boolean anyMatch = employeeData.stream().map(Employee::getAge).anyMatch(age -> age < 18);
System.out.println(anyMatch);

// noneMatch(Predicate p)─检查是否没有匹配的元素。
//startsWith("雷") 匹配第一个字符串
// 练习:是否存在员工姓"雷"
boolean noneMatch = employeeData.stream().noneMatch(e -> e.getName().startsWith("雷"));
System.out.println(noneMatch);

// findFirst——返回第一个元素
Optional<Employee> first = employeeData.stream().findFirst();
System.out.println(first);

// findAny—返回当前流中的任意元素
Optional<Employee> any = employeeData.parallelStream().findAny();
System.out.println(any);

// count—返回流中元素的总个数
long count = employeeData.stream().count();
System.out.println(count);

// max(Comparator c)—返回流中最大值
// 练习: 返回最大的年龄:
Optional<Integer> max = employeeData.stream().map(Employee::getAge).max(Integer::compareTo);
System.out.println(max);

// min(Comparator c) - 返回流中最小值
// 练习:返回最小年龄的员工
Optional<Employee> min = employeeData.stream().min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
System.out.println(min);

// forEach(Consumer c)—内部迭代
employeeData.stream().forEach(System.out::println);
//使用的是集合的遍历操作
employeeData.forEach(System.out::println);
}

归约

1
2
reduce(T iden, BinaryOperator b);//可以将流中元素反复结合起来,得到一个值。返回T
reduce(BinaryOperator b);//可以将流中元素反复结合起来,得到一个值。返回Optional<T>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//2. 归约
@Test
public void test2(){
//reduce(T identify, BinaryOperator b)
//将流中的元素反复结合起来,得到一个值,返回T
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
//identify:0 初始值为0
Integer reduce = list.stream().reduce(0, (d1, d2) -> d1 + d2);
System.out.println(reduce);

//reduce(BinaryOperator b)
//将流中的元素反复结合起来,得到一个值,返回Optional<T>
Optional<Integer> reduce1 = list.stream().reduce((d1, d2) -> d1 + d2);
System.out.println(reduce1);
}

收集

1
collect(Collector c);//将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
Collectors接口
toList方法
  • 返回类型:List
  • 作用:将流中的元素收集到List
toSet方法
  • 返回类型:Set
  • 作用:把流中的元素收集到Set
toCollection方法
  • 返回类型:Collection
  • 作用:将流中的元素收集到创建的集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//3. 收集
@Test
public void test3(){

//collect(Collect c) 将流转换为其他形式
//list 有序
List<Integer> list = Arrays.asList(1, 3, 5, 7);
List<Integer> integerList = list.stream().filter(num -> num > 2).collect(Collectors.toList());
System.out.println(integerList);

//set 无序
Set<Integer> integerSet = list.stream().filter(num -> num > 2).collect(Collectors.toSet());
System.out.println(integerSet);
}

Optional类

  • 是一个容器类(java.util.Optional),可以保存类型T值,代表这个值存在,或者仅仅保存bull,表示这个值不存在

创建Optional类对象方法

1
2
3
Optional.of(T t);//创建一个Optional实例,t必须为非空
Optional.empty();//创建一个空的Optional实例
Optional.ofNullable(T t);//t可以为null
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
@Test
public void test1(){
Girl girl = new Girl();
//girl = null;//报错空指针异常
//Optional.of(T t) 创建一个Optional实例,t必须非空
Optional<Girl> optionalGirl = Optional.of(girl);
System.out.println(optionalGirl);

//Optional.empty() 创建一个空的Optional实例
//Optional.ofNullable(T t) 创建一个Optional实例,t可以为null
Optional<Girl> optionalGirl1 = Optional.ofNullable(girl);
//当 girl 为null时 输出Optional.empty
System.out.println(optionalGirl1);
}

@Test
public void test2(){

Boy boy = new Boy();
boy = null;
String girlName = getGirlName(boy);
System.out.println(girlName);
}

//使用optional类的getGirlName()
public String getGirlName(Boy boy){

Optional<Boy> boyOptional = Optional.ofNullable(boy);
//boy1一定不为null 当boy为null时 输出1号
Boy boy1 = boyOptional.orElse(new Boy(new Girl("1号")));
Girl girl = boy1.getGirl();
Optional<Girl> girlOptional = Optional.ofNullable(girl);
//girl1一定不为null 当girl为null输出2号
Girl girl1 = girlOptional.orElse(new Girl("2号"));

return girl1.getName();
}

判断Optional容器中是否包含对象

1
2
boolean isPresent();//判断是否包含对象
void ifPresent(Consumer<?super T> consumer);//如果有值,就执行Consumer接口的实现代码,并且该值会作为参数传给它

获取Optional容器的对象

1
2
3
4
T get();//如果调用对象包含值,返回该值,否则抛异常
T orElse(T other);//如果有值则将其返回,否则返回指定的other对象。
T orElseGet(Supplier<? extends T>other);//如果有值则将其返回,否则返回由Supplier接口实现提供的对象
T orElse Throw(Supplier<? extends X>exceptionSupplier);//如果有值则将其返回,否则抛出由Supplier接口实现提供的异常