java8新特性

本文最后更新于:2023年11月16日 下午

Java8新特性

Lambda表达式与函数式接口

函数式接口

  1. Consumer 消费器, 作用是消费一个T类型的对象, 并没有返回.
  • void accept(T t) : 有输入无输出

  1. Supplier 供给器, 作用是供给一个T类型的对象, 不需要参数.
  • T get() : 无输入有输出

  1. Function<T, R> 转换器, 作用是输入一个T类型对象, 经过处理, 返回的是R类型对象.
  • R apply(T t) : 有输入有输出

  1. Predicate 判定器, 作用是输入一个T类型对象, 经过某种判断, 返回true或false
  • 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
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package java8;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.junit.Test;

import javabean.Student;


/**
* 函数式接口
* 只有一个抽象方法的接口, 可以用@FunctionalInterface修饰
*
* Consumer<T> 消费器, 作用是消费一个T类型的对象, 并没有返回.
* void accept(T t) : 有输入无输出
*
* Supplier<T> 供给器, 作用是供给一个T类型的对象, 不需要参数.
* T get() : 无输入有输出
*
* Function<T, R> 转换器, 作用是输入一个T类型对象, 经过处理, 返回的是R类型对象.
* R apply(T t) : 有输入有输出
*
* Predicate<T> 判定器, 作用是输入一个T类型对象, 经过某种判断, 返回true或false
* boolean test(T t) : 有输入有固定输出布尔
*
* 方法引用 : 接口中的抽象方法的模式(输入和输出) 和 Lambda体中的方法调用是一致时, 就可以简化写法.
* 类或对象 :: 方法名
*
*/

public class FunctionTest {

@Test
public void exer22() {
//Supplier<Student> supplier2 = () -> new Student();
Supplier<Student> supplier2 = Student::new;
System.out.println(supplier2.get());
}

@Test
public void test42() {
//Function<Integer, String> function2 = t -> String.valueOf(t);
Function<Integer, String> function2 = String::valueOf;
System.out.println(function2.apply(1112));
}

@Test
public void test32() {
//Supplier<Double> supplier2 = () -> Math.random();
Supplier<Double> supplier2 = Math::random;
System.out.println(supplier2.get());
}

@Test
public void test12() {
//Consumer<String> consumer2 = t -> System.out.println(t);
Consumer<String> consumer2 = System.out::println;
consumer2.accept("lkjxlkcjccc");
}

// 写一个判定器, 判断一个学生是否及格
@Test
public void exer4() {
Predicate<Integer> predicate1 = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return t>= 60;
}
};
boolean test = predicate1.test(100);
System.out.println(test);

Predicate<Integer> predicate2 = t -> t >= 60;
System.out.println(predicate2.test(100));
}

@Test
public void test5() {
Predicate<Integer> predicate1 = new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return t % 2 == 0;
}
};
boolean test = predicate1.test(83);
System.out.println(test);

Predicate<Integer> predicate2 = t -> t % 2 == 0;
System.out.println(predicate2.test(20));
}

// 写一个转换器, 把学生对象转换成字符串, 内容是姓名+分数
@Test
public void exer3() {
Function<Student, String> function1 = new Function<Student, String>() {
@Override
public String apply(Student t) {
return t.getName() + ":" + t.getScore();
}
};
String apply = function1.apply(new Student(2, "小刚", 5, 80));
System.out.println(apply);

Function<Student, String> function2 = t -> t.getName() + ":" + t.getScore();
System.out.println(function2.apply(new Student(1, "小花", 2, 100)));
}

@Test
public void test4() {
Function<Integer, String> function1 = new Function<Integer, String>() {
@Override
public String apply(Integer t) {
return String.valueOf(t);
}
};

String apply = function1.apply(9238);
System.out.println(apply);

Function<Integer, String> function2 = t -> String.valueOf(t);
System.out.println(function2.apply(1112));
}

// 写一个供给器, 每调用一次供给一个学生对象
@Test
public void exer2() {
Supplier<Student> supplier1 = new Supplier<Student>() {
@Override
public Student get() {
return new Student();
}
};
Student student = supplier1.get();
System.out.println(student);

Supplier<Student> supplier2 = () -> new Student();
System.out.println(supplier2.get());
}

@Test
public void test3() {
Supplier<Double> supplier = new Supplier<Double>() {
@Override
public Double get() {
return Math.random();
}
};
System.out.println(supplier.get());

Supplier<Double> supplier2 = () -> Math.random();
System.out.println(supplier2.get());
}

@Test
public void test2() {
Supplier<Integer> supplier1 = new Supplier<Integer>() {
@Override
public Integer get() {
return 100;
}
};
Integer integer = supplier1.get();
System.out.println(integer);

Supplier<Integer> supplier2 = () -> 100;
Integer integer2 = supplier2.get();
System.out.println(integer2);
}

// 写一个消费器, 消费一个Student对象.
@Test
public void exer1() {
Consumer<Student> consumer1 = new Consumer<Student>() {
@Override
public void accept(Student t) {
System.out.println(t);
}
};
consumer1.accept(new Student());

Consumer<Student> consumer2 = t -> System.out.println(t);
consumer2.accept(new Student(1, "小花", 2, 50));
}

@Test
public void test1() {
Consumer<String> consumer1 = new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println(t);
}
};
consumer1.accept("alsdkjfalksdjf");

Consumer<String> consumer2 = t -> System.out.println(t);
consumer2.accept("lkjxlkcjccc");
}
}

Stream流

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
160
161
162
163
164
165
166
167
168
169
170
package java8;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Test;

import javabean.Student;
import javabean.StudentTest;
/**
* Stream :
* 1) 不保存数据, 只负责处理数据
* 2) 处理数据不会造成原始数据的变化 , 每次处理都会产生新的流
* 3) 所有操作都是延迟执行的, 只有终止操作执行时才执行中间操作
* 4) 每个流只能"消费"一次, 消费过后就作废.
* 5) 单向, 一次性使用, 可以支持高并发...
*
* 典型的操作 :
* 1) 创建流(获取流)
* 1) 从集合获取流, 集合.stream();
* 2) 从数组获取流, Arrays.stream(Xxx[] arr);
* 3) 基于散数据, Stream.of(T... objs)
* 4) 使用供给器, 无限流
* 2) 中间操作, 多个中间操作就形成流水线, 是延迟执行的, 中间操作可以省略
* ***filter(Predicate p) : 让流中的每个对象都经过判定器, 如果结果为true留下, 如果是false丢弃. 产生新流
* distinct(); 把流中的数据去重并产生新流, 依据对象的hashCode和equals
* limit(long maxSize) 限制流中的最大数据量
* skip(long n) 跳过前n个元素
* ***map(Function f) 让流中的每个对象都转换为新对象, 所以它的结果的流全变了.
* sorted() 把流中的对象排序 , 自然排序
* *sorted(Comparator c) 定制排序
*
* 3) 终止操作, 一旦中止, 所有的中间操作就开始执行, 终止操作是必须的.
* ***forEach(Consumer c) : 让流中的每个对象都经过消费器消费一下.
* findFirst() 返回流中的第一个对象
* **count() 计数
* **collect(采集器) 可以把结果集采集到一个新的容器中.
* ***reduce(BinaryOperator op) 把流中的对象两两处理最后产生一个结果
*
* Optional是一容器, 里面放一个引用, 如果引用为空, 获取时直接抛异常.
* 防止空指针.
*/
public class StreamTest {
@Test
public void exer6() {
List<Student> collect = StudentTest.getList()
.stream()
.distinct()
.filter(t -> t.getGrade() == 3)
.filter(t -> t.getScore() < 60).sorted((o1, o2) -> -(int)(o1.getScore() - o2.getScore()))
.collect(Collectors.toList());
for (Student student : collect) {
System.out.println(student);
}
}

// 找出全校最高分
@Test
public void exer5() {
Optional<Double> reduce = StudentTest.getList().stream().distinct().map(t -> t.getScore()).reduce((d1, d2) -> d1 > d2 ? d1 : d2);
Double orElse = reduce.orElse((double) 999);
System.out.println(orElse);
}

@Test
public void exer4() {
long count = StudentTest.getList().stream().distinct().count();
System.out.println(count);
}

@Test
public void exer3() {
Optional<Student> findFirst = StudentTest.getList()
.stream()
.distinct()
.filter(t -> t.getGrade() == 4)
.filter(t -> t.getScore() < 60).sorted((o1, o2) -> -(int)(o1.getScore() - o2.getScore()))
.limit(2).findFirst();
//Student student = findFirst.get();
Student student = findFirst.orElse(new Student()); // 最大化减少空指针
System.out.println(student);
}

// 3年级没有及格的同学倒序, 取出前2个.
@Test
public void exer2() {
StudentTest.getList()
.stream()
.distinct()
.filter(t -> t.getGrade() == 3)
.filter(t -> t.getScore() < 60).sorted((o1, o2) -> -(int)(o1.getScore() - o2.getScore()))
.limit(2).forEach(System.out::println);
}

@Test
public void test9() {
StudentTest.getList().stream().distinct().sorted((t1, t2) -> (int)(t1.getScore() - t2.getScore())).forEach(System.out::println);
}

@Test
public void test8() {
StudentTest.getList().stream().distinct().map(t -> t.getScore()).forEach(System.out::println);
}

@Test
public void Test7() {
// 第6个到第10个
StudentTest.getList().stream().distinct().skip(10).limit(5).forEach(System.out::println);
}

// 找出5年级姓张的同学
@Test
public void exer1() {
List<Student> list = StudentTest.getList();
list.stream().filter(t -> t.getGrade() == 5).filter(t -> t.getName().startsWith("张")).forEach(System.out::println);
}

@Test
public void test62() {
List<Student> list = StudentTest.getList();
list.stream().filter(t -> t.getGrade() == 3).filter(t -> t.getScore() >= 60).forEach(System.out::println);
}

@Test
public void test6() {
List<Student> list = StudentTest.getList();
Stream<Student> stream = list.stream();
Stream<Student> stream2 = stream.filter(t -> t.getGrade() == 3);
Stream<Student> stream3 = stream2.filter(t -> t.getScore() >= 60);
stream3.forEach(System.out::println);
}

@Test
public void test5() {
Stream.generate(Math::random).limit(10).forEach(System.out::println);// 无限流
}

@Test
public void test4() {
Stream<Integer> generate = Stream.generate(() -> 200); // 无限流
generate.forEach(System.out::println);
}

@Test
public void test3() {
Stream<Number> of = Stream.of(3.22, 9.33, 4.88, 4.2, 8, 9);
of.forEach(System.out::println);
}

@Test
public void test2() {
String[] arr = {"kjsf", "qqa", "cv", "XXX"};
Stream<String> stream = Arrays.stream(arr);
stream.forEach(System.out::println);
}

@Test
public void test1() {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add((int)(Math.random() * 20));
}
System.out.println(list);

Stream<Integer> stream = list.stream();
stream.forEach(System.out::println);

}
}


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