如何使用Java Stream API替换代码中的双层嵌套循环?
解答
完全可以用Stream API替换这段嵌套循环,核心是用flatMap打平嵌套的角色列表结构,再直接收集为目标Map即可,改写后的逻辑和原循环行为完全一致。
改写后代码
原有角色分组逻辑无需改动,仅替换两层for循环部分即可:
// 原有角色分组逻辑保持不变,注意确保分组键和后续取数的键(user.getPassword())业务逻辑对齐 Map<String, List<Role>> roleByUserUsername = roles.stream() .collect(Collectors.groupingBy(/* 此处为你实际返回用户名的业务逻辑 */ Role::getRoleId, Collectors.toList())); List<User> users = List.of(new User(), new User()); // Stream实现替换嵌套循环 Map<String, User> userByRoleId = users.stream() // 过滤无匹配角色列表的用户,避免空指针,若业务保证键一定存在可删除该行 .filter(user -> roleByUserUsername.containsKey(user.getPassword())) // 打平每个用户对应的角色列表,生成角色ID与用户的键值对 .flatMap(user -> roleByUserUsername.get(user.getPassword()).stream() .map(role -> Map.entry(role.getRoleId(), user)) ) // 收集为HashMap,重复键时保留后遍历的用户,和原循环put的覆盖逻辑完全一致 .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldVal, newVal) -> newVal, HashMap::new ));
逻辑对齐说明
- 空值防护:新增的
filter步骤是对原代码的补全,原代码如果遇到用户password没有对应角色分组时,会因为遍历null抛出空指针,如果你的业务逻辑能确保所有用户都有匹配的角色分组,可以删除该过滤步骤。 - 重复键规则:原循环中如果同一个角色ID被多个用户关联,后遍历到的用户会覆盖之前的存入值,
toMap的第三个参数合并函数就是对齐这个覆盖逻辑,不会出现报错。 - 容器类型:最后指定
HashMap::new作为收集容器,和原代码声明的HashMap类型完全匹配,无额外类型转换问题。
内容的提问来源于stack exchange,提问作者Alex UHG
相关产品推荐
相关产品推荐

