Java8特性使用Function代替分支语句
作者:一马平川1 发布时间:2021-09-05 07:29:09
传统的多分支方式(圈复杂度为6):
public String order(String type) {
if ("1".equals(type)) {
return "1";
} else if ("2".equals(type)) {
return "2";
} else if ("3".equals(type)) {
return "3";
} else if ("4".equals(type)) {
return "4";
} else if ("5".equals(type)) {
return "5";
} else {
return "none";
}
}
使用Function函数式编程的新方式:
private Map<String, Function<String, String>> map = new HashMap<>();
public String order2(String type){
init();
Function<String, String> fun = map.get(type);
String result = fun.apply(type);
return result;
}
public void init() {
map.put("1", a -> {
System.out.println("执行1分支");
return a + "1";
});
map.put("2", a -> {
System.out.println("执行2分支");
return a + "22";
});
map.put("3", a -> {
System.out.println("执行3分支");
return a + "333";
});
map.put("4", a -> {
System.out.println("执行4分支");
return a + "4444";
});
map.put("5", a -> {
System.out.println("执行5分支");
return a + "55555";
});
}
圈复杂度为0;
总结:
1.Function是一个接口,它完整的样子是这样: Function<T,R>,其中T表示接受一个T类型的入参,R表示返回一个R类型的出参,注意: 既然入参和出参都是一个泛型,那就说明可以适用于任何种类的方法,如果方法需要多个入参,可以把它们封装成T类型的入参VO, 如果出参也需要有多个参数,也可以把它们封装为一个R类型的出参VO.
2. apply方法是function函数的统一执行标志性方法,它接受第一条提到的T t,返回第一条提到的R r,不管function函数体有多复杂,统统按apply执行,就像所有的线程统统用start开始执行.
3. 以前在有很多if-else的场合时,也想过把决定分支的入参(用type表示)和所执行的代码建立映射关系,但那时候因为不懂Function,心里想Map里面只能装数据类型,像分支逻辑这种不是数据类型,没法装.如今学习了Function,发现它把代码逻辑也封装得了,正好满足了我的设想.真的太好用了.
4. 以前用if-else执行多分支时, 走入不同分支还需要一个个对照,现在用了函数式编程,直接根据map查映射关系就找到了,很是方便.
最后总结:
以后遇到if-else较多的场合,可以考虑使用Function函数代替
普通的方法是将一种数据类型作为参数, 而Function方法是将一种方法或表达式作为参数.
=======================补充: 与策略模式的对比=======================
策略模式也是为了解决分支过多问题,此外它还解决另一个大问题: 避免代码侵入, 新增策略不需要修改原有策略代码.此处主要对比第一点: 解决分支过多
策略模式通过两层结构,完美实现了传入不同的策略,执行不同的方案,这与if-else的目标是一致的,当然与Function的目标也是一致的.
传入1, 选择策略1,执行策略1
传入2,选择策略2, 执行策略2
如何实现传入N,就能选择策略N呢? 使用映射表Map<String, Strategy>, 这点和Function的思想是一样,只不过策略模式通过类型获取封装好的策略实例,而Function通过类型获取封装好的策略方法.
从广义上说, if-else, Function, 策略模式,它们三者都是策略,解决的都是分支问题,只不过粒度由小到大,重量级不同而已.
如何选择呢?
能用if-else就不用Function,能用Function就不用策略模式
简单的,就用轻量级的
复杂的,就用重量级的.
===============题外思考: Map的三种用法================
初级: Map<String, 普通数据类型>======>通过一个数据可以获取另一个数据
中级: Map<String, 函数/表达式>=======> 通过一个数据可以获取一个方法
高级: Map<String, 模式>=============> 通过一个数据可以获取一个设计
来源:https://www.cnblogs.com/wangxuejian/p/13630024.html
猜你喜欢
- 在使用springmvc的时候,后台@RequestBody接受的是一个json格式的字符串,一定是一个字符串。我们可以通过@Request
- 本文实例讲述了java实现简单的英文文本单词翻译器功能。分享给大家供大家参考,具体如下:直接上代码:package fanyi;import
- 引言最近在工作中结合线程池使用 InheritableThreadLocal 出现了获取线程变量“错误&rdqu
- 最近在研究springboot实现FastJson解析json数据的方法,那么今天也算个学习笔记吧!添加jar包:<dependenc
- 前言现在很多web应用,做过web项目的童鞋都知道,web结果由html+js+css组成,html结构都有一定的规范,数据动态交互可以通过
- 本文实例讲述了Java * 和AOP应用。分享给大家供大家参考,具体如下:一 点睛 * 在AOP(Aspect Orient Progr
- 借用@Caching实现入参是基本类型的:@Caching(evict={@CacheEvict(value = Cache.CONSTAN
- 此解决方案是针对window的,因为日志默认保存路径在C盘,linux忽略。学习RocketMQ过程中,总是出现com.alibaba.ro
- 之前我们在使用vue进行 h5 表单录入的过程中,遇到了Android软键盘弹出,覆盖 h5页面 输入框 问题,在此进行回顾并分享给大家:系
- 这篇文章主要介绍了设计模式在Spring框架中的应用汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 比如在类上使用该注解 @Alias("dDebtEntity")则在mapper.xml文件中resultType=&q
- 在谈 JVM 内存区域划分之前,我们先来看一下 Java 程序的具体执行过程,我画了一幅图。Java 源代码文件经过编译器编译后生成字节码文
- 走马灯是一种常见的效果,本文讲一下如何用 PageView 在 Flutter 里实现一个走马灯, 效果如下,当前页面的高度比其它页面高,切
- 继承什么是继承呢?继承(Inheritance)是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接
- 本文实例为大家分享了flutter实现倒计时加载页面的具体代码,供大家参考,具体内容如下效果图实现步骤1、pubspec.yaml中添加依赖
- 一、概述在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依
- 前言有时候我们会在属性注入的时候添加@Lazy注解实现延迟注入,今天咱们通过阅读源码来分析下原因一、一个简单的小例子代码如下:@Servic
- 测试参数设置:1、循环调用new A()实现堆溢出,java.lang.OutOfMemoryError: Java heap space,
- 前言我们经常会被问到这么一个问题:SpringBoot相对于spring有哪些优势呢?其中有一条答案就是SpringBoot自动注入。那么自
- 本篇使用java自带的MessageDigest实现对文本的md5加密算法,具体代码如下: /** *@Description