Inverse Map where getValue returns 一个列表

Inverse Map where getValue returns a List

我想将 Map<String, List<Object>> 转换为 Map<String, String>。如果只是 Map<String, Object> 在 Java8;

中很容易
stream().collect(k -> k.getValue().getMyKey(), Entry::getKey);

但这不起作用,因为在我的示例中 getValue returns a List Map<List<Object>, String>。假设对象包含要用作键的 getter 并且 Object 不包含第一个映射中的键。

有什么想法吗?

流过对象列表并提取您需要的密钥,然后 map --> flatten --> toMap

source.entrySet()
      .stream()
      .flatMap(e -> e.getValue()
                     .stream()
                     .map(x -> new SimpleEntry<>(x.getMyKey(), e.getKey())))
      .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));

如果预计会有重复的 getMyKey() 值,请使用合并函数:

source.entrySet()
      .stream()
      .flatMap(e -> e.getValue()
                     .stream()
                     .map(x -> new SimpleEntry<>(x.getMyKey(), e.getKey())))
      .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue, (l, r) -> l));

注意: 以上使用源映射键作为结果映射的值,因为这似乎是您在 post 中说明的内容,如果您希望源映射的键保留为结果映射的键,然后将 new SimpleEntry<>(x.getMyKey(), e.getKey()) 更改为 new SimpleEntry<>(e.getKey(),x.getMyKey()).

如果偏好可以在映射为 key 的多个值中选择 any,您可以简单地使用:

Map<String, List<YourObject>> existing = new HashMap<>();
Map<String, String> output = new HashMap<>();
existing.forEach((k, v) -> v.forEach(v1 -> output.put(v1.getMyKey(), k)));

本质上,这会将 'first' 这样的 myKey 与其对应的值(即现有地图的 key)一起放置。