一个 Java Optional + Stream 重构的小例子

查看 85|回复 7
作者:allenzhangSB   
public Optional lastLog(Collection shopIds) {
    List allAppIds = StreamUtils.map(appDao.findAll(), App::getId);
    List logs = new ArrayList();
    shopIds.forEach(sid -> {
        allAppIds.forEach(aid -> {
            MyLog lastLog = logDao.findLast(aid, sid, null, LocalDate.now().plusDays(1));
            if (Objects.nonNull(lastLog)) {
                logs.add(lastLog);
            }
        });
    });
    if (CollectionUtils.isEmpty(logs)) {
        return Optional.empty();
    }
    logs.sort(Comparator.comparing(MyLog::getTime));
    return Optional.of(Iterables.getLast(logs));
}
public Optional lastLog(Collection shopIds) {
    if (shopIds.isEmpty()) {
        return Optional.empty();
    }
    var allAppIds = appDao.findAllId();
    var end = LocalDate.now().plusDays(1);
    return shopIds.stream()
            .flatMap(shopId -> allAppIds.stream().flatMap(appId -> logDao.findLast(appId, shopId, end).stream()))
            .max(Comparator.comparing(MyLog::getTime));
}
我们用的 java 11 ,部分方法 java 8 可能没有
类名和方法名有做部分处理
原来的方法不知道为什么主动用了 optional 但还是写成这么一大坨
调整后的 early return 其实也能合并到 optional 里串起来,不过想想还是算了,反倒显得更麻烦
另外这个 max 是 idea 自动提示的调整,一开始是照着原方法的思路写成 sorted + findFirst
idea 很多 warning 都可以很方便的 alt + enter 直接重构掉
copilot 锐评:
Overall, the refactored implementation is more concise and readable than the original implementation, and makes use of functional programming constructs to achieve the same result. It also avoids the use of nested loops, which can be harder to read and understand.

optional, mylog, lastlog, return

yazinnnn   
重构后还是在循环中查 db, 这个是最应该重构掉的
oneisall8955   
如果是查库的话, 为啥不直接写 sql?
anonydmer   
日志表分库分表了吗?循环里面查 db 有影响
tulongtou   
看起来就是对一个 appID 和一个 shopID 两个 id 集合做了笛卡尔集的遍历查最后一条日志,在不考虑楼上几位说的性能的前提下我更乐意写成:
shopIDs.stream()
.flatMap( s -> appIDs.stream().map( a -> new Pair(s, a)) )
.map(p -> logDAO.findLast(p.first(), p.second(), end)
.max(xxx)
第一步单独构建两个 id 集合的笛卡尔集(其实用个别的库可能比 stream 更方便)
第二步遍历取数据,这一步其实是可以利用 Stream 的并行计算的
第三步 max
oldshensheep   
循环里面操作数据库真是最应该优化的地方
xuanbg   
你写代码是不是一句 SQL 不用写,全用 Java 处理
App 表也不知道里面存的什么东西,没改前的 appDao.findAll(),我也是惊呆了。
xuanbg   
换我写的话,一句 sql 直接搞定。。。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部