将多个值关联到同一个 key的map(key可以重复的map)示例

在 Java 中,标准的 Map 接口要求 key 必须唯一 ,如果需要 key 可重复 且保持 插入顺序 的数据结构,可以使用以下方案:

1. 使用 List<Map.Entry<K, V>>

最直接的方式是用链表存储键值对,允许重复 key:

java 复制代码
import java.util.*;

// 创建可重复 key 的链表
List<Map.Entry<String, Integer>> list = new ArrayList<>();

// 添加元素(key 可重复)
list.add(new AbstractMap.SimpleEntry<>("key1", 1));
list.add(new AbstractMap.SimpleEntry<>("key1", 2)); // 重复 key
list.add(new AbstractMap.SimpleEntry<>("key2", 3));

// 遍历所有元素(保持插入顺序)
for (Map.Entry<String, Integer> entry : list) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

// 查找特定 key 的所有值
list.stream()
    .filter(e -> "key1".equals(e.getKey()))
    .forEach(e -> System.out.println("key1 值: " + e.getValue()));

2. 使用 Guava 的 Multimap

Google Guava 库提供的 Multimap 可以将多个值关联到同一个 key:

java 复制代码
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

// 创建可重复 key 的 Multimap(保持插入顺序)
Multimap<String, Integer> multimap = ArrayListMultimap.create();

// 添加元素(key 可重复)
multimap.put("key1", 1);
multimap.put("key1", 2); // 重复 key
multimap.put("key2", 3);

// 获取 key 对应的所有值(返回 Collection)
Collection<Integer> values = multimap.get("key1"); // 返回 [1, 2]

// 遍历所有键值对
multimap.entries().forEach(entry -> 
    System.out.println(entry.getKey() + " : " + entry.getValue())
);

3. 自定义 MultiMap

如果不想引入外部依赖,可以自定义一个包装类:

java 复制代码
import java.util.*;

public class MultiMap<K, V> {
    private final List<Map.Entry<K, V>> entries = new ArrayList<>();

    // 添加键值对(允许重复 key)
    public void put(K key, V value) {
        entries.add(new AbstractMap.SimpleEntry<>(key, value));
    }

    // 获取 key 对应的所有值
    public List<V> get(K key) {
        List<V> result = new ArrayList<>();
        for (Map.Entry<K, V> entry : entries) {
            if (Objects.equals(key, entry.getKey())) {
                result.add(entry.getValue());
            }
        }
        return result;
    }

    // 遍历所有键值对
    public void forEach(BiConsumer<K, V> action) {
        entries.forEach(entry -> action.accept(entry.getKey(), entry.getValue()));
    }

    // 其他方法(size、isEmpty 等)...
}

// 使用示例
MultiMap<String, Integer> multiMap = new MultiMap<>();
multiMap.put("key1", 1);
multiMap.put("key1", 2);
multiMap.forEach((k, v) -> System.out.println(k + " : " + v));

选择建议

  • 简单场景 :直接使用 List<Map.Entry<K, V>>
  • 需要丰富 API :引入 Guava 的 Multimap
  • 不想依赖外部库 :自定义 MultiMap

无论哪种方案,都能实现 key 可重复保持插入顺序 的需求。

相关推荐
ZHE|张恒3 小时前
Spring Bean 生命周期
java·spring
q***38515 小时前
SpringCloud实战十三:Gateway之 Spring Cloud Gateway 动态路由
java·spring cloud·gateway
小白学大数据5 小时前
Python爬虫伪装策略:如何模拟浏览器正常访问JSP站点
java·开发语言·爬虫·python
程序员西西6 小时前
SpringBoot接口安全:APIKey保护指南
java·spring boot·计算机·程序员·编程·编程开发
summer_west_fish6 小时前
单体VS微服务:架构选择实战指南
java·微服务·架构
v***8576 小时前
Ubuntu介绍、与centos的区别、基于VMware安装Ubuntu Server 22.04、配置远程连接、安装jdk+Tomcat
java·ubuntu·centos
烤麻辣烫6 小时前
黑马程序员大事件后端概览(表现效果升级版)
java·开发语言·学习·spring·intellij-idea
q***96586 小时前
Spring总结(上)
java·spring·rpc
思密吗喽6 小时前
宠物商城系统
java·开发语言·vue·毕业设计·springboot·课程设计·宠物
ss2737 小时前
019:深入解析可重入互斥锁:原理、实现与线程安全实践
java·数据库·redis