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: 而具体的方法也是相当的简单,就是不接受任何参数,返回一个结果: 对 ...
随机推荐
- matplotlib 设置标题 xy标题等
import matplotlib.pyplot as plt import matplotlib as mpl baseclass=[1,2,3,4] name = ['class1','class ...
- Solr6.4.2异常:org.apache.solr.common.SolrException: Error opening new searcher
版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明. 原文链接:https://www.cnblogs.com/chenghu/p/13840021.html Solr版本6.4.2 启动S ...
- HTML 的属性
HTML 属性赋予元素意义和语境. 下面的全局属性可用于任何 HTML 元 属性 描述 accesskey 规定激活元素的快捷键. class 规定元素的一个或多个类名(引用样式表中的类). cont ...
- Rust借用机制的理解分析
Rust初学者大多会遇到这样的问题: 为什么同一资源不可被同时可变借用和不可变借用? 为什么Rc一定只能是只读的,一定要配合std::cell系列(Cell,RefCell,UnsafeCell)才能 ...
- CentOS 环境变量编辑、保存、立即生效的方法
方法一: 该方法只能修改临时配置文件,当每次系统重启后,配置文件将失效 假如我的安装路径如下:/home/oracle/app/oracle/product/11.2.0/dbhome_1/bin 那 ...
- Hive LLAP
body { margin: 0 auto; font: 13px / 1 Helvetica, Arial, sans-serif; color: rgba(68, 68, 68, 1); padd ...
- win10系统出现“VMware Workstation与Device/Credential Guard不兼容”的解决办法
办公室win10 64位系统安装的VMware Workstation,有一天启动时出现提示"VMware Workstation 与 Device/Credential Guard 不兼容 ...
- Java数据结构-01顺序表
一.定义 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列. 二.存储分类 1.顺序存储: ①简述:是指将线性表中的各个元素依次存放在一组地址连续的存储单元中,通常将这种方 ...
- c库中sprintf
用法:sprintf指的是字符串格式化命令,主要功能是把某个数据写入某个字符串中: 我的理解就是,将某个其它类型的数据按着某一格式写入char *a,因此叫格式化命令: 语法: #include< ...
- django 框架模型之models常用的Field
1. django 模型models 常用字段 1.models.AutoField 自增列 = int(11) 如果没有的话,默认会生成一个名称为 id 的列 如果要显式的自定义一 ...