如何优雅地交换Map中的键和值

我已经知道如何以艰难的方式完成它并使其工作 – 迭代条目并“手动”交换。 但我想知道,像这么多任务一样,这个问题能否以更优雅的方式解决。

我读过这篇文章 ,遗憾的是它没有优雅的解决方案。 我也没有可能使用任何花哨的Guava BiMaps或jdk之外的任何东西(已经定义了项目堆栈)。

我可以假设我的地图是双射的,顺便说一下:)

标准API / Java运行时不提供双向映射,因此唯一的解决方案是迭代所有条目并手动交换它们。

你可以做的是创建一个包装类,它包含两个映射,并在内部执行双put()因此您可以快速获得两个数据视图。

[编辑]此外,由于开源,您不必包含第三方库,您只需将所需的类复制到您自己的项目中。

如果您没有选择使用第三方库,我不认为以下代码如此丑陋(尽管某些脚本语言确实有优雅的方法):

 //map must be a bijection in order for this to work properly public static  HashMap reverse(Map map) { HashMap rev = new HashMap(); for(Map.Entry entry : map.entrySet()) rev.put(entry.getValue(), entry.getKey()); return rev; } 
 Map map = new HashMap<>(); Map swapped = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 

地图不像列表,可以通过交换头部尾部来反转。

地图中的对象具有计算位置,并且使用值作为键并且将键作为值来重新计算存储位置,从而构建另一个地图。 没有优雅的方式。

但是,有双向地图。 这些可能适合您的需求。 我会重新考虑使用第三方库。

有些工作可以简化到某一点,而不是更多。 这可能就是其中之一!

如果你想使用Java集合apis来完成这项工作,那么蛮力就是要走的路 – 它会很快(除非集合很大)并且它将是一段显而易见的代码。

如果您有权访问apache commons-collections,则可以使用MapUtils.invertMap 。

注意:未定义重复值时的行为。

(回复此,因为这是“java反向地图”的第一个谷歌结果)。

作为回答https://stackoverflow.com/a/42091477/8594421的提示

这仅在地图不是HashMap且不包含重复值时才有效。

 Map newMap = oldMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 

抛出一个例外

java.lang.IllegalStateException:重复键

如果有多个值。

解决方案:

 HashMap newMap = new HashMap<>(); for(Map.Entry entry : oldMap.entrySet()) newMap.put(entry.getValue(), entry.getKey()); // Add inverse to old one oldMap.putAll(newMap);