Lambda表达式与函数式接口
# Lambda表达式
java8中引入了Lambda表达式是函数式接口的一个匿名函数定义实现类,类似js里的闭包。
Lambda可以大大简化函数式接口的实现代码,可读性更好。
- ->左边: 函数传入的参数,编译器会自动推断参数类型,不需要显示指定。当只有一个参数时,可以省略()
- ->右边: 函数执行的逻辑,如果只有一行代码,可以省略掉{},可以没有返回值。
ExecutorService pool = Executors.newSingleThreadExecutor();
CountDownLatch cdl = new CountDownLatch(2);
pool.submit(new Runnable() {
@Override
public void run() {
System.out.println("java8之前的写法");
cdl.countDown();
}
});
pool.submit(() -> {
System.out.println("Lambda表达式写法");
cdl.countDown();
});
cdl.await();
pool.shutdown();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 函数式接口
只有一个抽象方法的接口就是函数式接口,通常适用@FunctionalInterface注解来修饰。例如:Runnable、Comparator和Callable。也可以自定义一个函数式接口。
jdk已经定义了很多常用的函数式接口
函数式接口 | 抽象方法 | 说明 |
---|---|---|
Consumer< T > | void accept(T t) | 消费接口,通常用来遍历处理数据 |
Supplier< T > | T get() | 供给接口,没有入参,返回一个对象 |
Function<T, R> | R apply(T t) | 函数接口,需要一个入参,返回一个对象 |
Predicate< T > | boolean test(T t) | 断言接口,通常用来校验数据 |
除了这些之外还有很多多XxxConsumer, XxxSupplier, XxxFunction, XxxPredicate的函数式接口,基本上大同小异,只是参数个数不同。
# 示例
// Lambda创建一个比较器
Comparator<Integer> com = (o1, o2) -> o2 - o1;
List<Integer> list1 = Arrays.asList(1, 20, 30, 13, 40);
List<Integer> list2 = Arrays.asList(1, 20, 30, 13, 40);
list1.sort(com);
System.out.println(list1);
// 省去Comparator定义
list2.sort((o1, o2) -> o2 - o1);
System.out.println(list2);
Consumer<Integer> c1 = i -> {
i = i * 2;
System.out.println("i * 2 = " + i);
};
c1.accept(10);
Supplier<String> s1 = () -> "fjx" + Instant.now().toEpochMilli();
System.out.println(s1.get());
Function<Long, String> f1 = l -> "fjx" + l;
System.out.println(f1.apply(Instant.now().toEpochMilli()));
Predicate<String> p1 = str -> str == null;
System.out.println(p1.test("fjx"));
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
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
Last Updated: 2024/04/23, 01:30:37