将多个值关联到同一个 key的map(key可以重复的map)示例
在 Java 中,标准的 Map
接口要求 key 必须唯一,如果需要 key 可重复 且保持 插入顺序 的数据结构,可以使用以下方案:
1. 使用 List<Map.Entry<K, V>>
最直接的方式是用链表存储键值对,允许重复 key:
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:
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
类
如果不想引入外部依赖,可以自定义一个包装类:
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 可重复 且 保持插入顺序 的需求。