Java8 lambda 实战

本篇内容摘自《Java8 实战》

在阅读本篇文章之前,我希望你能了解什么是行为参数化——它允许你定义一个代码块来表示一个行为,然后传递它,利用这个概念,你就可以编写更为灵活且可重复使用的代码。

在行为参数化那篇博客中,我们最后写出了这样的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Demo4 {

public static void main(String[] args) {

List<Apple> apples = filterApplesByPredicate(AppleUtil.getApples(), new AppleGreenColorPredicate());
for (Apple apple : apples) {
System.out.println(apple);
}
}


public static List<Apple> filterApplesByPredicate(List<Apple> inventory, ApplePredicate predicate) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (predicate.test(apple)) {
result.add(apple);
}
}
return result;
}
}

这里有一个问题,我们要筛选绿色苹果的时候编写了一个类AppleGreenColorPredicate去实现ApplePredicate接口,但是有时候这个方法可能只会使用一次,如果这时候还要按照上面的方法去做的话,就显得有些不太合适。那么我们要如何去做呢?这时候我们想到了一个匿名内部类,代码如下

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 Demo5 {

public static void main(String[] args) {

List<Apple> apples = filterApplesByColor(AppleUtil.getApples(), new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "green".equals(apple.getColor());
}
});

for (Apple apple : apples) {
System.out.println(apple);
}

}


public static List<Apple> filterApplesByColor(List<Apple> inventory, ApplePredicate predicate) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (predicate.test(apple)) {
result.add(apple);
}
}
return result;
}
}

这样我们就可以不用创建一个实现类去实现ApplePredicate接口,但是匿名内部类不太友好,它占用了很多空间,让我们的代码显得很笨重与啰嗦,让代码显得不那么易读。那有没有办法去解决这个问题呢,答案是有的,在java8中,我们可以使用lambda表达式 去改造之前的代码,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Demo6 {

public static void main(String[] args) {

List<Apple> apples = filterApplesByColor(AppleUtil.getApples(), apple -> "green".equals(apple.getColor()));

for (Apple apple : apples) {
System.out.println(apple);
}

}


public static List<Apple> filterApplesByColor(List<Apple> inventory, ApplePredicate predicate) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (predicate.test(apple)) {
result.add(apple);
}
}
return result;
}
}

我想你应该发现了,之前匿名内部类的地方被这样一句代码代替了——apple -> "green".equals(apple.getColor()),在->的左边是参数列表,apple是简写,我们可以写成这样——(Apple apple)-> "green".equals(apple.getColor()),在->的右边是函数主体,这样写让我们的代码变得简洁很多。之所以我们能使用lambda表达式是依赖于类型推断,这是由编译器通过上下文环境推断而出。

比如我们要对苹果的重量从大到小进行排序

1
2
3
4
5
public static void main(String[] args) {
List<Apple> apples = AppleUtil.getApples();
apples.sort(Comparator.comparing(Apple::getWeight));
apples.forEach(System.out::println);
}

当苹果的重量一样,我们按照苹果的颜色来排序也是可以做到的,如下

1
2
3
4
5
6
7
public class Demo7 {
public static void main(String[] args) {
List<Apple> apples = AppleUtil.getApples();
apples.sort(Comparator.comparing(Apple::getWeight).thenComparing(Apple::getColor));
apples.forEach(System.out::println);
}
}

未完待续。。。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×