将具有字符串集的映射作为键转换为具有字符串的映射 (Java)

Convert Map with Set of Strings as key to Map with Strings (Java)

问题不难,我已经用自己的方法解决了,但我想听听你的意见,也许有什么方法可以改进这个选项? Java8-11.

Map<Set<String>, User> --> Map<String, User>

想象一下,集合中的元素不会重复。再注意一点:许多唯一键可以指向相同的值。

我用下面的代码做了这个:

Map<String, User> result = new HashMap<>();
existingMap.forEach((set, user) -> set.forEach(item -> result.put(set, user)));

所以,我的问题是 - 有更好的方法吗?我的意思是,也许 Stream API 已经有一些方法可以做到这一点?在 'collect' 方法的范围内

这个问题无法解决

考虑以下几点:

  1. ("Bill", "Tom", "Alice") -> User1
  2. ("Bill", "Tom", "Jane") -> User2

这对结构1(Map<Set<String>, User>)有效,但对结构2(Map<String, User>)无效,因为它会导致数据丢失(有关Bill和Tom的信息将丢失)。

您可以考虑的另一种结构是从 Map<Set<String>, User>Map<String, Set<User>> 的转换,这不会导致数据降级。

编辑:根据评论假设数据丢失是可以接受的,正常的 for 循环解决方案是:

Map<String, User> results = new HashMap<>();
for (Set<String> key : existing.keySet())
{
    User v = existing.get(key);
    for (String k : key)
    {
        results.put(k, v);
    }
}

如果你想使用收集器,你可以先做一个flatMap,然后toMap:

Map<String, User> result = existingMap.entrySet().stream().flatMap(
        entry -> entry.getKey().stream()
            .map(s -> Map.entry(s, entry.getValue()))
    )
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

或者如果您只想使用 collect(这与您原来的方法更相似):

Map<String, User> result = existingMap.entrySet().stream().collect(
    HashMap::new,
    (map, entry) -> entry.getKey().forEach(x -> map.put(x, entry.getValue())),
    HashMap::putAll
);