Map结合Function函数式接口的巧妙之处
需求:在给定 List 集合中,需根据不同的算法规则,选取计算方式并返回结果;
例如:[1, 2, 3, 4, 5] List 集合中都是 Integer 类型数据,根据提供的算法规则,sum 求和,min 求最小值,max 求最大值等;
使用场景:需要根据指定 key,选取不同的逻辑处理方式;
一、使用枚举类实现
(1)定义枚举类DataEnum,需实现指定的计算接口,根据不同的算法规则【使用枚举类中默认的 name 属性】,来选取不同的算法计算方式;
(2)代码如下:
// 计算方式接口定义
public interface Icalculate { // 计算方式
Integer calculate(List<Integer> datas); } // 定义枚举类,实现接口
public enum DataEnum implements Icalculate { SUM{
@Override
public Integer calculate(List<Integer> datas) {
return datas.stream().reduce(0, (element1, element2) -> element1 + element2);
}
}, MIN{
@Override
public Integer calculate(List<Integer> datas) {
Optional<Integer> min = datas.stream().min(Comparator.comparingInt(o -> o));
return min.orElse(null);
}
}, MAX{
@Override
public Integer calculate(List<Integer> datas) {
Optional<Integer> max = datas.stream().max(Comparator.comparingInt(o -> o));
return max.orElse(null);
}
}; // 根据算法规则,获取指定的计算方式【挪用了枚举类继承Enum中的name属性】
public static DataEnum of(String name) {
Optional<DataEnum> dataEnum = Arrays.stream(DataEnum.values()).filter(element -> element.name().equalsIgnoreCase(name)).findAny();
return dataEnum.orElse(null);
} } 枚举类实现
(3)测试样例及结果


public class DataEnumTest { public static void main(String[] args) {
DataEnum dataEnum = DataEnum.of("max");
if (!Objects.isNull(dataEnum)) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("max = " + dataEnum.calculate(list));
}
} }
结果:max = 5
测试样例及结果
二、使用Map结构结合Function实现【常用】
(1)定义FunctionUtil工具类,结合Java8的Function函数式接口实现;
(2)代码实现:
public class FunctionUtil { // 定义Map结构,key: 算法规则,value: 存放指定的计算方式
private static Map<String, Function<List<Integer>, Integer>> calculateMap = new HashMap<>(); // 静态代码块,初始化Map结构,定义指定算法规则的计算方式
static {
calculateMap.put("SUM", list -> list.stream().reduce(0, Integer::sum));
calculateMap.put("MIN", data -> data.stream().min(Comparator.comparingInt(o -> o)).orElse(null));
calculateMap.put("MAX", data -> data.stream().max(Comparator.comparingInt(o -> o)).orElse(null));
}
}
(3)测试样例和结果:


public class Test { public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Integer min = FunctionUtil.calculateMap.get("MIN").apply(list);
Integer max = FunctionUtil.calculateMap.get("MAX").apply(list);
Integer sum = FunctionUtil.calculateMap.get("SUM").apply(list);
System.out.println("min = " + min + ", max = " + max + ", sum = " + sum); } }
结果:min = 1, max = 5, sum = 15
测试样例及结果
三、Java8 的函数式接口之 Function 使用
(1)常见的函数式接口集合,供参考:详解JAVA8函数式接口{全}
1、Consumer<T> :消费型接口 void accept(T t); 2、Supplier<T> :供给型接口 T get(); 3、Function<T,R> :函数型接口 R apply(T t); 4、Predicate<T> :断言型接口 boolean test(T t);
(2)举例使用 Function 作为参数使用
public class FunctionTest { // 提供一个 Function 入参泛型方法【适用于不同的数据类型】
private static <T, R> R calculate(T t, Function<T, R> function) {
return function.apply(t);
} public static void main(String[] args) {
Function<List<Integer>, Integer> sumFunc = list -> list.stream().reduce(0, Integer::sum);
Integer sum = FunctionTest.calculate(Arrays.asList(1, 2, 3, 4, 5), sumFunc); Function<List<Integer>, Integer> maxFunc = list -> list.stream().max(Comparator.comparingInt(o -> o)).orElse(null);
Integer max = FunctionTest.calculate(Arrays.asList(1, 2, 3, 4, 5), maxFunc); Function<List<Integer>, Integer> minFunc = list -> list.stream().min(Comparator.comparingInt(o -> o)).orElse(null);
Integer min = FunctionTest.calculate(Arrays.asList(1, 2, 3, 4, 5), minFunc); System.out.println("sum = " + sum + ", min = " + min + ", max = " + max);
} } 结果:sum = 15, min = 1, max = 5
使用函数式接口作为形参时,会为方法的封装提供了很大的便利性,不会受到类型的约束和限制,使得方法的使用场景更加广泛和可扩展性;
Map结合Function函数式接口的巧妙之处的更多相关文章
- java8学习之Function与BiFunction函数式接口详解
Function接口: 上次中已经使用了Function的apply()方法,但是在这个接口中还存在三个具体实现的方法,如下: 下面来仔细的将剩下的方法学习一下: compose(): 首先来读一下该 ...
- Java 8中一些常用的全新的函数式接口
这一篇属于菜鸟级博客,只是介绍了一些在Java 8中新出现的一些很有用的接口,通过一些简单的例子加以说明,没有深入地阐述. 函数式接口 什么是函数式接口? 函数式接口,@FunctionalInter ...
- java8中使用函数式接口
使用函数式接口 Predicate @FunctionalInterface interface Predicate<T>{ boolean test(T t); } public sta ...
- 8000字长文让你彻底了解 Java 8 的 Lambda、函数式接口、Stream 用法和原理
我是风筝,公众号「古时的风筝」.一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...
- 第46天学习打卡(四大函数式接口 Stream流式计算 ForkJoin 异步回调 JMM Volatile)
小结与扩展 池的最大的大小如何去设置! 了解:IO密集型,CPU密集型:(调优) //1.CPU密集型 几核就是几个线程 可以保持效率最高 //2.IO密集型判断你的程序中十分耗IO的线程,只要大于 ...
- 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑
大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...
- Java8内置的函数式接口
JDK 1.8 API 包含了很多内置的函数式接口.其中就包括我们在老版本中经常见到的 Comparator 和 Runnable,Java 8 为他们都添加了 @FunctionalInterfac ...
- JAVA8之函数式接口
由于JDK8已经发布一段时间了,也开始逐渐稳定,未来使用JAVA语言开发的系统会逐渐升级到JDK8,因为为了以后工作需要,我们有必要了解JAVA8的一些新的特性.JAVA8相对JAVA7最重要的一个突 ...
- java8学习之Supplier与函数式接口总结
Supplier接口: 继续学习一个新的函数式接口--Supplier,它的中文意思为供应商.提供者,下面看一下它的javadoc: 而具体的方法也是相当的简单,就是不接受任何参数,返回一个结果: 对 ...
随机推荐
- spring boot:用spring security加强druid的安全(druid 1.1.22 / spring boot 2.3.3)
一,druid的安全保障有哪些环节要注意? 1,druid ui的访问要有ip地址限制 2,用户必须要有相应的权限才能访问druid 3,关闭重置功能 说明:stat-view-servlet.url ...
- centos8用firewalld搭建防火墙
一,firewalld的systemd管理命令 启动:systemctl start firewalld 关闭:systemctl stop firewalld 查看状态:systemctl stat ...
- java-类和数组
java内存划分 Java的内存划分为5个部分: 1.栈 (Stack) : 存放的都是方法中的局部变量,方法的运行一定要在栈当中 局部变量: 方法的参数,或者是方法()内部的变量 作用域: 一旦超出 ...
- IDEA 半天卡住buid(编译)不动
[号外号外!] 最终解决办法并不复杂,关键在于"遇见问题,怎么样层层分析,多条路径试错,最终解决问题的思路或者能力"--资深码农的核心竞争力之一 背景 今天结束完最近2个月的一个项 ...
- 【事件中心 Azure Event Hub】Event Hub Java SDK的消费端出现不消费某一个分区中数据的情况,出现IdleTimerExpired错误消息记录
问题情形 使用Java SDK编写的Event Hub消费端应用,随机性遇见了某个分区没有消费消息的情况,在检查日志时候,有发现IdelTimeExpired的错误记录.在重启应用后,连接EventH ...
- 如何在windows Server 2008虚拟机上安装SQLServer2008数据库
一.环境准备 1.cn_windows_server_2008_r2_standard_enterprise_datacenter_web_x64_dvd_x15-50360.iso 2.NDP452 ...
- 原生JS实现动态折线图
原生JS实现动态折线图 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...
- Angular双向绑定简单理解
在使用Antd的时候,一直很好奇里面的双向绑定的自定义组件是怎么做的. 因为之前一直用,没有去细看文档. 今天抽空来简单的撸一下. 在ng中,()是单向数据流,从视图目标到数据源,[()]这样就是双向 ...
- IDEA Cannot resolve plugin org.apache.maven.plugins:maven-site-plugin:3.8.2-plugin爆红错误
如果确认本地库存在,maven仓库配置正确,将其显式声明出来,问题解决 <!--报找不到该依赖的错误, 本地库又存在,将其显式声明在这里,问题解决--> <plugin> &l ...
- D. Yet Another Problem On a Subsequence 解析(DP)
Codeforce 1000 D. Yet Another Problem On a Subsequence 解析(DP) 今天我們來看看CF1000D 題目連結 題目 略,請直接看原題 前言 這題提 ...