行为参数化使用lambda传递代码
行为参数化传递代码
行为参数化是为了帮助我们应对不断变化的需求实现快速开发
比如在List 苹果集合中我们需要实现:找出绿色苹果找出大苹果(重量大于500g)找出绿色大苹果
对于这样的场景,我们可以将对集合的需求就可以抽象为一个行为。假设场景:
1. 需要筛选绿苹果public static List filterGreenApples(List inventory) { List result = new ArrayList(); for(Apple apple: inventory){ if( "green".equals(apple.getColor() ) { //筛选绿色 result.add(apple); } } return result; }需要筛选各种颜色(将颜色抽象为参数)public static List filterGreenApples(List inventory) { List result = new ArrayList(); for(Apple apple: inventory){ if( "green".equals(apple.getColor() ) { result.add(apple); } } return result; }需要大于500g的苹果或者绿苹果 public static List filterApples(List inventory, String color, int weight, boolean flag) { List result = new ArrayList(); for (Apple apple: inventory){ if ( (flag && apple.getColor().equals(color)) || (!flag && apple.getWeight() > weight) ){ result.add(apple); } } return result; } 这样确实比较蠢,不写注释的话,你能根据方法名判断flag是干啥的不?
这个时候我们就可以运用" 行为参数化 " 来帮我们解决问题。
首先我们来抽象需求:我们考虑的
是苹果,需要根据Apple的某些属性(比如它是绿色的吗?重量超过xxx克吗?)来返回一个
boolean值。我们把它称为谓词(即一个返回boolean值的函数)。让我们定义一个接口来对选
JDK中为我们提供了一个接口public interface ApplePredicate{ boolean test (Apple apple); }
现在我们可以根据不同需求实现不同的行为public class AppleHeavyWeightPredicate implements ApplePredicate{ public boolean test(Apple apple){ return apple.getWeight() > 150; //筛选大于150g的 } } public class AppleGreenColorPredicate implements ApplePredicate{ public boolean test(Apple apple){ return "green".equals(apple.getColor()); //绿色的 } }public static List filterApples(List inventory, ApplePredicate p){ List result = new ArrayList<>(); for(Apple apple: inventory){ if(p.test(apple)){ result.add(apple); } } return result; }
最终实现了行为参数化的fliterAppler方法看起来是不错的public class AppleHeavyWeightPredicate implements ApplePredicate{ public boolean test(Apple apple){ return apple.getWeight() > 150; } } public class AppleGreenColorPredicate implements ApplePredicate{ public boolean test(Apple apple){ return "green".equals(apple.getColor()); } } public class FilteringApples{ public static void main(String...args){ List inventory = Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120, "red")); List heavyApples = filterApples(inventory, new AppleHeavyWeightPredicate()); List greenApples = filterApples(inventory, new AppleGreenColorPredicate()); } public static List filterApples(List inventory, ApplePredicate p) { List result = new ArrayList<>(); for (Apple apple : inventory){ if (p.test(apple)){ result.add(apple); } } return result; } }
可是每次都还需要定义一个实现类再实例化,看起来好像十分的啰嗦。Java有一个机制称为匿名类,它可以让你同时
声明和实例化一个类。它可以帮助你进一步改善代码,让它变得更简洁。
下面的代码展示了如何通过创建一个用匿名类实现ApplePredicate的对象,重写筛选的例子:List redApples = filterApples(inventory, new ApplePredicate() { public boolean test(Apple apple){ return "red".equals(apple.getColor()); } });
但是不得不说匿名类真的很笨重,很多冗余的模版代码,而且还会有this指针的问题
引入Lambda我们可以做到这样子,避免了笨重了匿名类。List result = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor()));