如何将Java中键为项目名、值为用户列表的Map转换为反向映射?
解决方案:反转项目-用户映射为用户-项目映射
首先要明确:User类必须正确重写equals()和hashCode()方法,否则Map无法识别逻辑上相同的User对象。示例实现如下(基于id和name字段判断相等性):
class User { private int id; private String name; // 构造器、getter/setter方法省略 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return id == user.id && Objects.equals(name, user.name); } @Override public int hashCode() { return Objects.hash(id, name); } }
方案1:传统迭代方式(兼容Java 8及更早版本)
通过遍历原Map的键值对,逐个将用户与项目名关联到目标Map:
Map<String, List<User>> originalMap = new HashMap<>(); // 原Map初始化代码省略 Map<User, List<String>> reversedMap = new HashMap<>(); for (Map.Entry<String, List<User>> entry : originalMap.entrySet()) { String projectName = entry.getKey(); List<User> users = entry.getValue(); for (User user : users) { // 若用户不存在则新建列表,再添加项目名 reversedMap.computeIfAbsent(user, k -> new ArrayList<>()).add(projectName); } }
方案2:Java 8+ Stream API方式(代码更简洁)
利用Stream的flatMap展开用户-项目配对,再通过分组收集结果:
Map<User, List<String>> reversedMap = originalMap.entrySet().stream() .flatMap(entry -> entry.getValue().stream() .map(user -> new AbstractMap.SimpleEntry<>(user, entry.getKey())) ) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList()) ));
如果需要目标列表为可修改的ArrayList(默认Collectors.toList()返回的列表实现不确定),可以替换为:
Collectors.mapping(Map.Entry::getValue, Collectors.toCollection(ArrayList::new))
验证输出
遍历目标Map即可得到示例格式结果:
reversedMap.forEach((user, projects) -> System.out.printf("%-5s = %s%n", user.getName(), projects) );
输出内容:
Bob = [projectA] John = [projectA, projectB] Mo = [projectA, projectB, projectC]
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

