2.3 对付啰嗦
已经将行为抽象出来,但上述过程需要声明很多只要实例化一次的类。
2.3.1 匿名类
匿名类,可以同时声明和实例化一个类
2.3.2 第五次尝试:使用匿名类
List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "red".equals(apple.getColor());
}
});
匿名类仍不够友好
- 笨重,占用较多行数;
- 复杂情况下,令人费解;
测验2.2:匿名类谜题
public class MeaningOfThis {
public final int value = 4;
public void doIt() {
int value = 6;
Runnable r = new Runnable() {
public final int value = 5;
@Override
public void run() {
int value = 10;
System.out.println(this.value); // 5
System.out.println(value); // 10
System.out.println(MeaningOfThis.this.value); // 4
}
};
r.run();
}
}
2.3.3 第六次尝试:使用Lambda表达式
Java8通过引入Lambda表达式,更简洁地完成代码传递。
List<Apple> result = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor()));
2.3.4 第七次尝试:将List类型抽象化
通过泛型将类型抽象化,java8提供了函数式接口java.util.function.Predicate。
public static <T> List<T> filter(List<T> sourceList, Predicate<T> predicate) {
List<T> result = new ArrayList<>();
for (T t : sourceList) {
if (predicate.test(t)) {
result.add(t);
}
}
return result;
}
// invoke
List<Apple> redAppleList = filter(inventory, (Apple apple) -> "red".equals(apple.getColor()));
List<Integer> numbers = Lists.newArrayList(1, 2, 3, 4, 5);
// 筛选偶数
List<Integer> evenNumbers = filter(numbers, (Integer num) -> num % 2 == 0);