行业资讯 2025年08月6日
0 收藏 0 点赞 855 浏览 3897 个字
摘要 :

文章目录 1.什么是反转的Map? 2.反转具有唯一值的Map 2.1. 使用for循环 2.2. 使用Collectors.toMap() 3.反转具有重复值的Map 3.1. 使用for循环 3.2. 使用Collectors……




  • 1.什么是反转的Map?
  • 2.反转具有唯一值的Map
    • 2.1. 使用for循环
    • 2.2. 使用Collectors.toMap()
  • 3.反转具有重复值的Map
    • 3.1. 使用for循环
    • 3.2. 使用Collectors.groupBy()
  • 4.使用Guava库
    • 4.1. 使用Multimap
    • 4.2. 使用BiMap
  • 5.使用Apache Commons-Collections
    • 5.1. 使用BidiMap
    • 5.2. 使用MapUtils.invertMap()
  • 6.结论

这个Java教程将教我们如何使用不同的技术来反转给定的Map的keyvalue。我们将学习如何反转具有唯一值的Map,并在存在重复值时创建Multimap。

1.什么是反转的Map?

一个反转的Map <V, K> 是原始Map<K, V>的一个实例。原始Map的值成为结果Map的键,而原始Map的键成为值。

Map<String, String> map = Map.of(\"key1\", \"value1\", \"key2\", \"value2\");
System.out.println(map);   //{key1=value1, key2=value2}

//反转后
{value1=key1, value2=key2}

2.反转具有唯一值的Map

以下方法应该用于反转包含唯一值的Map,因为我们没有使用任何机制来解决重复的键/值。

2.1. 使用for循环

反转Map的最简单方式是使用循环。我们遍历Map的条目并将它们添加到一个新的Map中。在添加条目时,我们互换键和值。

Map<Integer, String> invertedMap = new HashMap<>();

for (Map.Entry<String, Integer> entry : originalMap.entrySet()) {
  invertedMap.put(entry.getValue(), entry.getKey());
}

2.2. 使用Collectors.toMap()

Stream API提供了Collectors.toMap()来方便地将Stream元素收集到Map中。我们需要遍历Stream元素并按相反的顺序收集条目。

Map<Integer, String> inverseMap = originalMap.entrySet()
        .stream()
        .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));

3.反转具有重复值的Map

假设Map中有一些具有重复值的条目。现在,在反转Map时,我们必须决定如何处理这些值,因为反转后的Map不允许重复的键。

通常,在这些情况下创建一个MultiMap是正确的解决方案。MultiMap类似于一个Map,不同之处在于可以有相同的键对应多个元素。

3.1. 使用for循环

在下面的示例中,使用一个List来存储一个键的多个值,从而得到一个Multimap。

Map<Integer, String> mapWithDuplicateValues = new HashMap<Integer, String>();
mapWithDuplicateValues.put(1, \"Value1\");
mapWithDuplicateValues.put(2, \"Value2\");
mapWithDuplicateValues.put(3, \"Value2\");

HashMap<String, List<Integer>> inverseMap = new HashMap<String, List<Integer>>();

for (Map.Entry<Integer, String> entry : mapWithDuplicateValues.entrySet()) {
  if (inverseMap.containsKey(entry.getValue())) {
    inverseMap.get(entry.getValue()).add(entry.getKey());
  } else {
    List<Integer> list = new ArrayList<Integer>();
    list.add(entry.getKey());
    inverseMap.put(entry.getValue(), list);
  }
}
System.out.println(inverseMap);   //{Value1=[1], Value2=[2, 3]}

3.2. 使用Collectors.groupBy()

在下面的示例中,Collectors.mapping()函数通过传递给收集器的方式,对重复值执行归约操作,将重复值收集到一个List中。

HashMap<String, List<Integer>> inverseMap = originalMap.entrySet()
      .stream()
      .collect(Collectors.groupingBy(Entry::getValue,
              Collectors.mapping(Entry::getKey, Collectors.toList())));

4.使用Guava库

Guava是由Google创建的开源Java库。它提供了许多有用的集合和接口。我们将使用以下Map来反转给定的Map。

4.1. 使用Multimap

Multimap是一个直接的实现,内部管理重复的值。

Multimap<Integer, String> multimap = ImmutableMultimap.of(1, \"Key1\", 1, \"Key2\", 2, \"Key3\");

System.out.println(multimap); //{1=[Key1, Key2], 2=[Key3]}

4.2. 使用BiMap

BiMap是一个双向Map,维护了Map的反向视图,即键和值颠倒的条目。此Map还确保不会在Map中存储重复的值或键。

BiMap<Integer, String> biMap = ImmutableBiMap.of(1, \"Key1\", 2, \"Key2\", 3, \"Key3\");
BiMap<String, Integer> inverseBiMap = biMap.inverse();

System.out.println(inverseBiMap); //{Key1=1, Key2=2, Key3=3}

还有一个名为HashBiMap的类,它由两个哈希表支持,一个用于键到值的映射,另一个用于值到键的映射。这个实现允许空键和值。

BiMap<Integer,String> originalMap = HashBiMap.create();
//add key-value pairs

BiMap<String, Integer> inversedMap = biMap.inverse();

5.使用Apache Commons-Collections

Apache Commons Collections库提供了各种实现和工具,以便轻松处理集合。我们将使用BidiMap和inverseBidiMap()方法来反转Map,方法与Guava类似。

5.1. 使用BidiMap

BidiMap接口允许在键和值之间进行双向查找。以下是该接口的不同实现:

  • DualHashBidiMap:它使用两个HashMap实例,以提供使用键或值快速查找条目。
  • DualLinkedHashBidiMap:它使用两个LinkedHashMap实例,以牺牲存储两组链表和映射条目的代价来进行快速查找。
  • TreeBidiMap:这个Map基于红黑树实现,保证键-值将根据键和值的自然顺序以升序方式存储。
  • DualTreeBidiMap:它使用两个TreeMap实例,使其比TreeBidiMap更昂贵,因为它将每个对象存储两次。我们可以使用inverseBidiMap()方法获得原始Map的反向视图。请注意,当找到重复值时,后面的键将覆盖前面的键。
BidiMap bidiMap = new DualHashBidiMap();
bidiMap.put(1, \"Value1\");
bidiMap.put(2, \"Value2\");

System.out.println(bidiMap.inverseBidiMap());         //{Value1=1, Value2=2}

5.2. 使用MapUtils.invertMap()

invertMap()方法返回一个新的HashMap,其中键和值被交换。请注意,如果原始Map对多个键有重复的值,返回的Map将包含其中一个键,但应该映射的确切键将未定义。

Map<Integer, String> hashMap = new HashMap<Integer, String>();
hashMap.put(1,\"Value1\");
hashMap.put(2,\"Value2\");
hashMap.put(3,\"Value2\");

Map<String,Integer> inversedMap1 = MapUtils.invertMap(hashMap);
System.out.println(inversedMap1);  //{Value1=1, Value2=3}

6.结论

在这个Java教程中,我们学习了如何使用不同的技术反转给定的Map,从for循环到Guava和Apache Commons的方法。我们还学习了如何反转具有重复值的Map。反转给定的Map的有效方式是使用外部库,如Guava或Apache Commons,而不是遍历条目。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9382.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号