JDK8之前的做法
现在需求是:我要从一群女孩中挑选出体重是50kg以下的。
以前的做法是
public List<girl> filterGirs(List<girl> list){
List<girl> result=new ArrayList<>();
for(girl e : list){
if(e.getWeight()<50){
result.add(e);
}
}
return result;
}
如果需求变了,还要挑选身高超过170cm,脸型是瓜子脸的呢,那样我们可以把身高,和脸型连同之前的体重作为参数,传递进去,例如:
public List<girl> filterGirs(List<girl> list,int weight,int high,stirng faceType){
List<girl> result=new ArrayList<>();
for(girl e : list){
if(e.getWeight()<weight&&e.getHigh()>high&&e.getFaceType().equals(aceType)){
result.add(e);
}
}
return result;
}
这样我就可以随心所欲的通过条件来筛选我们想要的女孩了,但是…
行为参数化
我从字面意思理解就是把筛选女孩的行为作为参数,传递进来。
首先我们定义一个接口,来对筛选行为建模
public interface GirlPredicate{
boolean test (girl g);
}
然后我们可以通过实现多个GirlPredicate 来代表不同的筛选行为,例如:
public class WeightPredicate implements GirlPredicate (){
public boolean test(girl g){
return girl.getWeight()<50 ; // 体重小于50kg
}
}
public class HighPredicate implements GirlPredicate (){
public boolean test(girl g){
return girl.getHigh()>175 ; // 身高大于175
}
}
然后筛选的时候可以这么写
public List<girl> fileterGirl(List<girl> list,WeightPredicate wp){
List<girl> result=new ArrayList<>();
for(girl e list){
if(wp.test(e)){
result.add(e)
}
}
return result;
}
行为参数化的优点发现了吗,以前的那种写法,如果需求变了的话,我们是需要修改之前的筛选方法的;但是行为参数话以后,我们只需要在实现一个满足要求的方法,当作参数传进去即可,个人感觉更简单也更符合面向对象的思想。
继续优化
将List类型抽象话 + 引入lambda表达式
public interface GirlPredicate<T>{
boolean test (T t);
}
----------------------------------------------------------------
public List<T> fileterGirl(List<T> t,GirlPredicate<T> gp){
List<T> result=new ArrayList<>();
for(T e list){
if(gp.test(e)){
result.add(e)
}
}
return result;
}
---------------------------------------------------------------------------
List<girl> result=fileterGirl(list,(gire g) -> g.getWeight()<50) //实现筛选体重小于50kg的女孩