You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java 8函数式风格改写仅变量类型不同的两段代码?

用函数式风格统一不同类型Optional的分支逻辑

这问题我之前也碰到过,核心就是利用Optional的方法链特性,绕开Long和UUID没有共同接口的限制,同时把嵌套的if-else改写成简洁的函数式代码。

解决方案(Java 9+)

直接用flatMap、or和orElseThrow串联逻辑,一行代码搞定:

String id = entity.legacyIndicator()
    .flatMap(__ -> entity.legacyId().map(Object::toString))
    .or(() -> entity.newId().map(Object::toString))
    .orElseThrow(() -> new IOException("No ID found."));

代码拆解说明

  1. 处理legacy分支:
    entity.legacyIndicator().flatMap(__ -> entity.legacyId().map(Object::toString))

    • 如果legacyIndicator存在,就尝试获取legacyId(Optional<Long>),通过Object::toString把Long转成String,得到Optional<String>。
    • 用flatMap而不是map,是为了避免出现Optional<Optional<String>>的嵌套结构,直接把结果扁平化。
    • 如果legacyIndicator不存在,这部分会返回空的Optional。
  2. 切换到new分支:
    .or(() -> entity.newId().map(Object::toString))

    • 当前面的Optional为空(也就是legacyIndicator不存在),就执行这个分支:获取newId(Optional<UUID>),同样用Object::toString转成String,得到Optional<String>。
    • Java 9新增的or方法接收一个Supplier<Optional<T>>,完美适配分支切换的场景。
  3. 统一异常处理:
    .orElseThrow(() -> new IOException("No ID found."))

    • 如果两个分支的ID都不存在(最终Optional为空),就抛出指定异常;否则返回转换后的ID字符串。
    • 这一步把原来两个分支里重复的throw逻辑统一起来,符合DRY原则。

Java 8兼容版本

如果还在使用Java 8(没有or方法),可以用orElseGet替代:

String id = entity.legacyIndicator()
    .flatMap(__ -> entity.legacyId().map(Object::toString))
    .orElseGet(() -> entity.newId().map(Object::toString))
    .orElseThrow(() -> new IOException("No ID found."));

这里orElseGet会在前面的Optional为空时,返回newId转换后的Optional<String>,后续逻辑和Java 9版本一致。

为什么能解决类型差异问题?

虽然Long和UUID没有实现共同接口,但它们都继承自Object,而Object本身就有toString()方法。我们用Object::toString这个方法引用,就能统一处理两种类型的转换,完全不需要额外定义接口或者包装类。

内容的提问来源于stack exchange,提问作者Andrew Cheong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:57:14