找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

394

积分

0

好友

48

主题
发表于 昨天 00:39 | 查看: 6| 回复: 0

Java 8 发布至今已经超过 10 年,其引入的 Lambda 表达式和 Stream API 早已被广泛讨论。但一个有趣的现实是:在企业级项目中,能够熟练且恰当地运用函数式编程来优化代码逻辑的开发者,似乎仍是少数派。

在日常的代码评审中,你是否也常被层叠嵌套的 if-else 语句困扰?这些条件分支让核心业务逻辑显得臃肿且不易读。我们能否借助函数式的思想,将这些“分支”巧妙地收敛起来呢?

基于这个想法,我尝试封装了几个简单的工具方法,并在团队中进行了实践,效果还不错。虽然封装本身看起来并不复杂,甚至有些“丑陋”,但它们确实能帮助我们在业务层减少大量的条件判断代码,让逻辑更清晰。下面就来分享一下这几个小工具。

Java多层if-else嵌套代码示例

isBlankAccept

这是第一个案例,源自于一种常见的模式:当某个字符串不为空时,才执行一段特定的业务逻辑。看下面这段典型的代码:

public void test(User user){
// ...
if(isBlank(user.getName())){
// doSomething
    wrapper.innerJoin(Order.class, on -> on.eq(Order::getUserId, User::getId)
            .eq(Order::getState, 10));
        wrapper.and(p -> p.like(Order::getAddress, n)
            .or().like(Order::getCode, n)
            .or().like(User::getName, n));
// doSomething       
  }
// ... 
}

这类场景非常普遍,比如参数校验后的处理、动态 SQL 拼接、或是根据条件生成特定内容等。其本质都是 “当条件 P 成立时,执行动作 A”

我们可以将这个模式抽象成一个函数式工具,将 if 判断隐藏在工具内部,让业务代码更专注于“要做什么”:

FunUtil.isBlankAccept(user.getName, n -> {
// doSomething
  wrapper.innerJoin(Order.class, on -> on.eq(Order::getUserId, User::getId)
        .eq(Order::getState, 10));
    wrapper.and(p -> p.like(Order::getAddress, n)
        .or().like(Order::getCode, n)
        .or().like(User::getN
ame, n));
// doSomething    
});

这样一来,业务方法中就少了一层缩进和一个 if 语句。实现这个工具方法非常简单:

public static void isBlankAccept(final CharSequence cs, Consumer<CharSequence> action){
if (isBlank(cs)) {
        action.accept(cs);
    }
}

这里的 isBlank 方法可以直接使用 Apache Commons Lang、Spring Framework 或 Hutool 等工具库中的实现,当然也可以自己编写。对应的 isNotBlankAccept 方法逻辑正好相反,按需实现即可。

isTrueRun

上面的 isBlankAccept 是针对字符串空值判断的特化方法。那么,对于更通用的布尔条件判断呢?这就是我们的第二个工具:isTrueRunisFalseRun

其核心思想是:如果条件为真,则执行一段代码逻辑。对于不需要参数的操作,可以使用 Runnable

public static void isTrueRun(final boolean flag, Runnable action){
if (flag) {
        action.run();
    }
}

如果需要传入参数给要执行的逻辑,则可以使用泛型结合 Consumer<T>

public static <T> void isTrueRun(boolean flag, T t, Consumer<T> action){
if (flag) {
        action.accept(t);
    }
}

// 使用示例
String name = “业余草”;
isTrueRun(FunUtil.isNotBlank(name), name, t -> {
    System.out.println(“Processing: “ + t);
// 业务逻辑
});

当逻辑需要两个参数时,可以进一步扩展到 BiConsumer<T, U>

public static <T, U> void isTrueRun(boolean flag, T t, U u, BiConsumer<T, U> action){
if (flag) {
        action.accept(t, u);
    }
}

// 使用示例
isTrueRun(true, name, wrapper, (t, w) -> {
    w.like(…, t);
});

isTrueRunGet

前两个案例的工具方法都没有返回值。但在实际开发中,我们经常需要根据条件计算并返回一个值。这就是第三个工具 isTrueRunGet 要解决的问题。

对于无参数但需要返回值的场景,可以使用 Supplier<T>

public static <T> T isTrueRunGet(final boolean flag, Supplier<T> action){
if (flag) {
// 执行并返回结果
return action.get();  
    }
// 或抛异常,或返回默认值
return null; 
}

// 使用示例
String result = isTrueRunGet(
    FunUtil.isNotBlank(name),
    () -> “Processed: “ + name.toUpperCase()
);

为了让方法更健壮,避免返回 null 导致潜在的 NullPointerException,我们可以增加一个默认值参数:

public static <T> T isTrueRunGet(final boolean flag, Supplier<T> action, T defaultValue){
if (flag) {
return action.get();
    }
return defaultValue;
}

// 使用示例
String result = isTrueRunGet(
    FunUtil.isNotBlank(name),
    () -> processName(name),
    “默认是业余草”
);

如果需要根据输入参数计算返回值,则可以使用 Function<T, R>

public static <T, R> R isTrueRunGet(final boolean flag, T input, Function<T, R> action, R defaultValue){
if (flag) {
return action.apply(input);
    }
return defaultValue;
}

// 使用示例
String result = isTrueRunGet(
    FunUtil.isNotBlank(name),
    name,
    t -> t.trim().toUpperCase(),
    “#业余草”
);

更进一步,为了更安全地处理可能为空的结果,我们可以让工具方法直接返回 Optional<T>,这是 Java 8 中处理空值的最佳实践之一:

public static <T> Optional<T> isTrueRunGet(final boolean flag, Supplier<T> action){
if (flag) {
return Optional.ofNullable(action.get());
    }
return Optional.empty();
}

// 使用
Optional<String> result = isTrueRunGet(
    FunUtil.isNotBlank(name),
    () -> processName(name)
);
result.ifPresent(System.out::println);

看到这里,可能有读者会指出:“你这些工具方法内部不还是用了 if 吗?” 没错,我们封装的目的并不是从地球上彻底消灭 if 关键字,而是将条件判断的细节与业务动作的执行进行解耦,提升业务代码的声明性和可读性。

PHP中复杂的条件判断示例

如果你追求的是极致的“无 if”风格,也可以使用三元表达式改造返回值版本的方法:

public static <T> T isTrueRunGet(boolean flag, Supplier<T> action, T defaultValue){
return flag ? action.get() : defaultValue;
}

广泛而恰当地使用这类函数式工具后,你的代码会变得更紧凑、更富表达力,当然,也可能让不熟悉这种范式的人觉得更像“诗”(或者别的什么)。

总结

归根结底,代码是写给人看的,其次才是让机器执行。本文分享这几个小工具,与其说是为了消灭 if-else,不如说是一次对函数式编程思维的轻度实践推广。

在实际开发中,我发现即便是 AI 生成的代码,也较少主动使用这类模式,除非在指令中明确要求。这或许说明,函数式编程不仅仅是一些语法糖,更是一种需要刻意练习和理解的思维方式

掌握 Lambda 表达式、Stream API 只是起点,如何像本文这样,将其思想融入日常工具封装与业务抽象,才是更进阶的课题。本文的示例仅是抛砖引玉,更多实用的函数式编程技巧和设计模式,可以在云栈社区的Java板块与大家深入探讨。

趣味求赞梗图




上一篇:TanStack全家桶:一套框架无关的前端状态管理解决方案
下一篇:Flink on k8s 实战:从网络插件到权限配置的踩坑与解决记录
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-18 21:32 , Processed in 0.225309 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表