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


猜你喜欢
- 前言:项目中数据分页是一个很常见的需求,目前大部分项目都会使用pagehelper进行分页,那么在使用的过程中是否考虑如下问题?一、基本集成
- 项目中肯定会遇到需要用户自己绘制地形的需求,然后根据地形自动生成房间。下面说说我在绘制地形的实现方法。我们百度可以看到很多关于自己创建mes
- 扩展:由于server端是存储了所有server与client的连接对象,因此我们是可以基于此demo的基础上实现聊天系统:* 每当一个与用
- 前言插入排序狭义上指的是简单插入排序(选择集合,比较大小,插入元素),广义上还应该包括希尔排序(分治思想)及其两种实现方式,最激动人心的是
- JetpackJetpack,我觉得翻译为“飞行器”更好听,因为Google针对编程历史乱象,整理出
- 前言Java多线程实现方式主要有四种:① 继承Thread类、实现Runnable接口② 实现Callable接口通过FutureTask包
- 首先是按行读取字符串import java.io.BufferedReader;import java.io.File;import jav
- java和javascript长得是如此地相像,那么它们是一回事儿吗?现在让我来揭晓答案吧!JavaScript 是一种嵌入式脚本文件,直接
- 突然心血来潮,想自己做个小程序玩玩,但是怎么把他做成一个exe文件,让大家能够更好的理解和使用呢,百度了一下,说是需要exe4j来生成,但是
- 一、Servlet3.0异步请求@WebServlet(value = "/async", asyncSupported
- 前言制作无边框窗口时,系统自带阴影会消失,这时就需要我自己给窗口添加阴影以防止窗口融入背景。添加阴影的方法很简单,直接用effect就可以了
- 需求输入手机号码,点击获取按钮,服务端接受请求发送短信用户输入验证码点击登录手机号码必须属于系统的注册用户,并且唯一手机号与验证码正确性及其
- 最近一直在看RecyclerView,较之ListView它确实是灵活多变,给予开发者更多自定义的空间,比如:需要添加头部和尾部、item的
- 目录问题产生如何解决总结问题产生默认生成的flutter工程,在启动时候会白屏,设备性能越差,白屏时间越长。原生Android开发也会遇到类
- 首先,引入依赖:<dependency> <groupId>org.springframe
- 在本文中,我们将介绍二进制搜索相对于简单线性搜索的优势,并介绍它在 Java 中的实现。1. 需要有效的搜索假设我们在wine-sellin
- kaptcha是一个开源的验证码实现库1.添加依赖<dependency> <groupId>com.g
- 一、什么是Memcached?Memcached是danga.com开发的分布式内存对象缓存系统,所谓分布式,意味着它不是本地的,而是基于网
- 前言我个人觉得,中间件的部署与使用是非常难记忆的;也就是说,如果两次使用中间件的时间间隔比较长,那基本上等于要重新学习使用。所以,我觉得学习
- Maven 组件界面介绍 如上图标注 1 所示,为常用的 Maven 工具栏,其中最常用的有:第一个按钮:Reimport All