java8的lamda表达式提供了有四种最常用的函数式接口类型:简单理解函数式接口:就是接口中只有一个抽象方法的接口
1:消费型接口:Consumer 有入参 无返回接口
2:供给型接口:Supplier 无入参 有返回结果
3:function接口:有入参 有返回结果
4:断言型接口Predicator: 判断返回结果是否true
现在模拟一个小小的需求:
一个集合:
List<UserInfo> userList = Arrays.asList(
new UserInfo(1,"张三",29),
new UserInfo(1,"李四",21),
new UserInfo(1,"王五",11),
new UserInfo(1,"赵六",8)
)
需求1:我们要取出年龄小于20周岁的员工
需求2:我们要取出名字含有(李)字的员工
方法一:
new一个集合,然后for循环,if(年龄小于20)则添加到new的集合中。
再new一个集合,然后for循环,if(名字含有李字)则添加到new的集合中。
这是没有任何策略的流水似实现。最容易理解。效率最低。如果有新的需求。就要sbb的擂代码。
方法二:采用策略设计模式
1:设计一个Filter接口。接口里面提供一个方法。方法名称就叫filterByAge() ,返回一个boolean类型。
/**
* : 方法描述信息
*
* @author liyy
* @date 2018-09-09 13:59
*/
public interface FilterPredicator<T> {
public boolean filter(T t);
}
2: 写一个实现类实现这个Filter接口,重写里面的方法。如果满足某个过滤条件返回true
package com.springmvc.filter;
import com.springmvc.pojo.UserInfo;
/**
* : 描述信息
*
* @author liyy
* @date 2018-09-09 14:01
*/
public class MyFilterPredicator implements FilterPredicator<UserInfo>{
@Override
public boolean filter(UserInfo userInfo) {
return userInfo.getAge()>20;
}
}
3:对集合采用实现中的策略进行过滤。就可以拿到最后需要的数据
public List<UserInfo> getListByAge(List<UserInfo> list,Filter<UserInfo> filter){
List<UserInfo> filterList = new ArrayList();
for(UserInfo u:list){
if(filter.filter(u)){
filterList.add(u);
}
}
}
4:直接调用getListByAge方法传入两个参数即可。此时如果新加一个需求按名字进行过滤。那么这里不需要添加任何代码。只
需要在接口实现类中。新增一个实现类即可。
List<UserInfo> users = getListByAge(list,new MyFilter());
以上就是根据实际的需求采用不同的策略进行筛选获取最终的结果。
那么还是觉得有点麻烦。我每新增一个需求就要新增一个实现类。这也蛮多的。可以接着优化我们的代码
那就是把我们的实现类变成匿名内部类。匿名内部类的作用一个两个:1:简化代码2:读复杂的业务逻辑提供内部支持。例如
我们常用的Comparator接口、Runnable接口
1: Comparator<UserInfo> comparator = new Comparator<UserInfo>() {
@Override
public int compare(UserInfo o1, UserInfo o2) {
return 0;
}
};
MyThread集成Thread抽象类
2: Thread t = new Runnable(new MyThread()){
@Override
public void run(){
}
}
改造我们现有的代码:
List<UserInfo> users = getListByAge(list,new MyFilter());代码改造成
List<UserInfo> users = getListByAge(userInfoList, new Filter<UserInfo>() {
@Override
public boolean filter(UserInfo userInfo) {
return userInfo.getAge()>20;
}
});
用匿名内部类就可以替换掉原有实现类。直接在filter方法里面写具体的策略。在java1.8之前这已经是最优代码没法再优化了
但是java1.8提供了更强大的流式处理。简单几行搞定上述需求
List<UserInfo> resultList = list.stream().filter(u -> u.getAge>20).collect(Collectors.toList());
一句就搞定了
加入我要输出用户的姓名呢?
List<String> nameList = list.stream().map(UserInfo::getName()).collect(Collectors.toList());
就是这么的NB.不服不行!
最后:java提供的最后一个函数是接口Predicator可以代替我们上面自定义的接口。java已经帮我们提供了!