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

如何用Java 8 Optional优化空检查及DAO调用代码?

优化方案:用Optional重构你的代码

第一步:修正selectById方法

你的初步尝试存在隐患:如果logs为空,logs.get(0)会直接抛出IndexOutOfBoundsException,而非返回Optional.empty()。既然你确定selectUserLogs返回的List永远非null,用Stream的findFirst()能更安全地生成Optional:

public Optional<UserLog> selectById(String userid) throws DataException {
    List<UserLog> logs = selectUserLogs(SQL_SELECT_BY_ID, userid);
    return logs.stream().findFirst();
}

列表为空时,该方法会直接返回Optional.empty(),既避免了索引越界问题,代码也更简洁符合语义。

第二步:优化调用方callingMethod

原调用代码有两个明显问题:一是重复调用selectById(userid)会触发两次数据库查询,浪费资源;二是嵌套null检查冗余,可读性差。用Optional的链式API可以完美解决:

基础优化版

public void callingMethod() {
    // 仅查询一次,避免重复操作
    Optional<UserLog> userLogOpt = userLogDao.selectById(userid);
    
    if (starttime != null 
        && FIVE_HOUR <= durationSinceStartTime()
        && userLogOpt.isPresent()
        && userLogOpt.get().getStartTime() != null) {
        log.warn("Logs came in late");
    }
}

更贴合Optional最佳实践的版本

用map方法简化空检查逻辑,让代码更流畅:

public void callingMethod() {
    boolean shouldWarn = starttime != null 
        && FIVE_HOUR <= durationSinceStartTime()
        && userLogDao.selectById(userid)
                     .map(UserLog::getStartTime)
                     .isPresent();

    if (shouldWarn) {
        log.warn("Logs came in late");
    }
}

这里map(UserLog::getStartTime)会把Optional<UserLog>转换为对应getStartTime返回值的Optional——如果UserLog不存在或getStartTime返回null,都会变成Optional.empty(),最后用isPresent()统一判断条件。

额外建议

  • 尽量消除嵌套null:如果getStartTime()也可能返回null,建议把它的返回类型改成Optional<LocalDateTime>(假设是时间类型),这样可以用flatMap替代map,彻底消除空检查:
    // 假设UserLog的getStartTime返回Optional<LocalDateTime>
    boolean shouldWarn = starttime != null 
        && FIVE_HOUR <= durationSinceStartTime()
        && userLogDao.selectById(userid)
                     .flatMap(UserLog::getStartTime)
                     .isPresent();
    
  • 遵循《Clean Code》原则:用Optional明确表达方法返回值可能为空的语义,让调用方一眼就能知晓如何处理空值,从根源避免NPE。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 06:28:29