一、什么是行为参数化?
从一个需求入手:农场主有一堆苹果的数据,他需要找出里面的绿苹果?
一堆苹果使用List<Apple>表示,那么从这一堆苹果中找出其中的绿色苹果,那还不简单吗?
苹果类:
//定义为一个有三属性的Apple类,省略了构造方法和set、get方法
public class Apple {
private String appleColor;
private Integer id;
private Integer weight;
}
找出绿色苹果的逻辑:
public class ScreenApple {
public static final String GREEN = "green Apple";
public List<Apple> screenAppleColor(List<Apple> list){
List<Apple> appleList = new ArrayList<>();
for (Apple apple : list){
if (GREEN.equals(apple.getAppleColor)){
appleList.add(apple);
}
}
return appleList;
}
}
逻辑相当的简单,就是将List中的苹果的appleColor取出来和绿色做对比就行了。但是,经过一夜的时间后,农场主说有新的需求了,就是找出苹果中重量大于150g的苹果。当然这也很简单,只需要将上面的代码复制一下,然后更改一下对比的那一行代码即可:
将
GREEN.equals(apple.getAppleColor)
改为
apple.getWeight() > 150
是不是也很简单。突然农场主说,能不能找出重量大于150g的绿苹果,你很不情愿的再去复制一边代码,将筛选的条件更改一下,虽然这个样你能解决问题,但是除了筛选条件的那一行,其他的所有代码都是重复的,这样太过于冗余,代码得不到复用,作为一个程序员,需要有一定的工匠精神,我们需要给代码做一些改变,需要将改变的地方行为参数化,因为代码中只有一个地方发生了更改,那么我们可不可以将这一段代码拿出来,作为一个参数进行传递,答案是可以的。在Java8之前使用的比较多的就是写一个函数式接口,然后为这个函数式接口编写实现类,实现了的方法就是上面所说的筛选条件,又或者是使用匿名内部类的形式,但是这两种实现方式都不够简洁,所以java8使用了新的知识点Lambda表达式。
二、使用Lambda表达式实现行为参数化。
还记得刚才找出绿苹果的处理逻辑吗?我们只需要在上面做一些修改就可以了:
public class ScreenApple {
public static <T> List<T> screenAppleColor(List<T> list, ApplePredicate<T> predicate){
List<T> appleList = new ArrayList<>();
for (T t : list){
//这里将筛选条件作为参数传进来
if (predicate.test(t)){
appleList.add(t);
}
}
return appleList;
}
}
那么你肯定好奇ApplePredicate<T>这个是什么?
答案:其实这就是那个函数式接口,接下来看看它的定义;
public interface ApplePredicate<T> {
boolean test(T t);
}
就这么简单。那么我们如何使用呢?接下来写一个main函数演示一下:
public class MainTest {
public static final String GREEN = "green Apple";
public static void main(String[] args) throws Exception {
//这个集合是空的 需要自己添加Apple
List<Apple> list = new ArrayList<>();
//处理逻辑
ScreenApple screenApple = new ScreenApple();
//使用lambda表达式:
//可以看到将(Apple apple) -> GREEN.equals(apple.getAppleColor())
//作为参数传递进去了
List<Apple> apples = screenApple.screenAppleColor(list, (Apple apple) -> GREEN.equals(apple.getAppleColor()));
//输出一下返回结果
apples.forEach( apple -> System.out.println(apple.getAppleName() + " " + apple.getId()));
}
}
使用匿名内部类实现方式:
//使用匿名内部类方式
// List<Apple> apples = screenApple.screenAppleColor(list, new ApplePredicate(){
// @Override
// public boolean test(Apple apple) {
// return GREEN.equals(apple.getAppleColor());
// }
// });
《Java2实战》学习笔记,记录一下。