结合HashMap与Java 8的Function和Optional消除ifelse判断

shigen坚持更新文章的博客写手,记录成长,分享认知,留住感动。个人IP:shigen

在文章的开头我们先从这些场景进入本期的问题:

  1. 业务代码中各种if-else有遇到过吗,有什么好的优化方式;
  2. java8出来这么多年了,Function、Optional有经常用到吗?

可能文字描述还是略显抽象,我们直接上代码:

java 复制代码
public class SimplifyIfElse {

    public String handleQuestion(String type, String detail) {
        if ("A".equals(type)) {
            return "call methodA to handle" + detail;
        } else if ("B".equals(type)) {
            return "call methodB to handle" + detail;
        } else if ("C".equals(type)) {
            return "call methodC to handle" + detail;
        } else {
            throw new IllegalArgumentException("invalid type: " + type);
        }
    }
}    

这种代码其实很常见的,使用起来也就是一行调用:

java 复制代码
    public static void main(String[] args) {
        assert new SimplifyIfElse().handleQuestion("B", "detail").equals("call methodB to handledetail");
    }

这里直接用的assert进行的断言验证。

但是有没有考虑到一些问题:

  • 这是明显的坏味道的代码,各种判断,看起来很是不舒服;
  • 后期加上同样的逻辑,是不是if-else的体量还会继续增加,维护的成本也在增加。

也许稍微有点经验的同学会想到我用策略模式、工厂方法等等来优化一下这段代码。可以,至少会设计模式的基本使用了,但是对于这样同类型的问题,我们没有必要整的这么复杂。

不管是策略模式还是工厂方法,其底层还是维护的一个hashMap,对应的key和value分别是问题标识和问题的解决方法。

掌握到这个核心,我们来优化下现存的代码:

java 复制代码
    private static final HashMap<String, Function<String, String>> QUESTION_HANDLER_MAP = new HashMap<>();

    static {
        QUESTION_HANDLER_MAP.put("A", detail -> "call methodA to handle" + detail);
        QUESTION_HANDLER_MAP.put("B", detail -> "call methodB to handle" + detail);
        QUESTION_HANDLER_MAP.put("C", detail -> "call methodC to handle" + detail);
    }

    public String handleQuestionV2(String type, String detail) {
        return Optional.ofNullable(QUESTION_HANDLER_MAP.get(type).apply(detail)).orElseThrow(() -> new IllegalArgumentException("invalid type: " + type));
    }

这里用到了java8的新特性,Function和Optional,其中:

  • Function是一个功能接口,Function<T,R>中的T和R都是范型,分别表示输入类型和输出类型;
  • Optional这里不再做过多的解释,就是优雅的判空

代码这样改造之后,后期只需要往QUESTION_HANDLER_MAP增添新的元素即可,大大的简化了代码。

当然常见的消除if-else代码的方式还有:

  1. 借助switch-case
  2. 借助枚举抽象
  3. SpringBoot的IOC能力

这里先在此点一下,有时间继续分享。附:代码截图:

与shigen一起,每天不一样!

相关推荐
xiaoye37085 小时前
Java 自动装箱 / 拆箱 原理详解
java·开发语言
YDS8296 小时前
黑马点评 —— 分布式锁详解加源码剖析
java·spring boot·redis·分布式
ZTLJQ6 小时前
数据的基石:Python中关系型数据库完全解析
开发语言·数据库·python
夏霞6 小时前
c# signlar 客户端传递参数给服务端配置方法
开发语言·c#
迷藏4947 小时前
**发散创新:基于 Rust的开源权限管理系统设计与实战**在现代软件架构中,**权限控制**早已不
java·开发语言·rust·开源
升鲜宝供应链及收银系统源代码服务7 小时前
《IntelliJ + Claude Code + Gemini + ChatGPT 实战配置手册升鲜宝》
java·前端·数据库·chatgpt·供应链系统·生鲜配送
daidaidaiyu7 小时前
Nacos实例一则及其源码环境搭建
java·spring
2301_818419017 小时前
C++中的解释器模式变体
开发语言·c++·算法
小江的记录本7 小时前
【Redis】Redis全方位知识体系(附《Redis常用命令速查表(完整版)》)
java·数据库·redis·后端·python·spring·缓存
摇滚侠7 小时前
Java 项目《谷粒商城-1》架构师级Java 项目实战,对标阿里 P6-P7,全网最强,实操版本
java·开发语言