You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LinkedHashMap存重复键后如何保留插入顺序并允许重复键?

实现保留插入顺序且允许重复键的"Map"结构

嘿,这个需求太常见啦——想要像LinkedHashMap那样记住键值对的插入顺序,但又不想让重复的键覆盖掉之前的值对吧?我给你几个实用的解决方案,你可以根据自己的场景来选:

方案1:基于LinkedHashMap封装多值Map

最直接的思路是把LinkedHashMap的值类型改成列表,每次插入时,如果键已经存在,就把新值追加到对应的列表里;如果不存在,就新建一个列表存放值。我们可以把这个逻辑封装成一个工具类,用起来和普通Map差不多:

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.AbstractMap.SimpleEntry;

public class OrderedMultiMap<K, V> {
    // 用LinkedHashMap保证键的插入顺序
    private final LinkedHashMap<K, List<V>> innerMap = new LinkedHashMap<>();

    // 自定义put方法:不覆盖,只追加
    public void put(K key, V value) {
        // computeIfAbsent会自动处理键不存在的情况,新建列表
        innerMap.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
    }

    // 获取某个键对应的所有值
    public List<V> get(K key) {
        return innerMap.getOrDefault(key, Collections.emptyList());
    }

    // 获取所有按插入顺序排列的键值对(包括重复键)
    public List<Map.Entry<K, V>> getAllEntries() {
        List<Map.Entry<K, V>> entries = new ArrayList<>();
        for (Map.Entry<K, List<V>> entry : innerMap.entrySet()) {
            K key = entry.getKey();
            for (V value : entry.getValue()) {
                entries.add(new SimpleEntry<>(key, value));
            }
        }
        return entries;
    }

    // 可选:添加其他常用方法,比如获取大小、清空等
    public int size() {
        return innerMap.values().stream().mapToInt(List::size).sum();
    }

    public void clear() {
        innerMap.clear();
    }
}

用法示例

把你原来的代码改成这样就行:

OrderedMultiMap<String, Object> myMap = new OrderedMultiMap<>();
myMap.put("a", list1);
myMap.put("e", list2);
myMap.put("i", list3);
myMap.put("o", list4);
myMap.put("u", list5);
myMap.put("g", list6);
myMap.put("a", list7);

// 遍历所有条目,会按插入顺序输出:a->list1, e->list2, ..., a->list7
for (Map.Entry<String, Object> entry : myMap.getAllEntries()) {
    System.out.println(entry.getKey() + " -> " + entry.getValue());
}

方案2:维护独立条目列表的自定义Map

如果需要更细粒度的控制(比如按插入索引获取某个键值对,或者明确区分每一次插入操作),可以同时维护一个条目列表和一个索引Map:

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.AbstractMap.SimpleEntry;
import java.util.stream.Collectors;

public class OrderedDuplicateMap<K, V> {
    // 用LinkedList保存所有插入的条目,保证顺序
    private final LinkedList<Map.Entry<K, V>> entryList = new LinkedList<>();
    // 用LinkedHashMap快速查找某个键对应的所有条目
    private final LinkedHashMap<K, List<Map.Entry<K, V>>> keyIndex = new LinkedHashMap<>();

    public void put(K key, V value) {
        Map.Entry<K, V> newEntry = new SimpleEntry<>(key, value);
        entryList.add(newEntry);
        keyIndex.computeIfAbsent(key, k -> new ArrayList<>()).add(newEntry);
    }

    // 获取所有按插入顺序排列的条目
    public List<Map.Entry<K, V>> getAllEntries() {
        return new ArrayList<>(entryList);
    }

    // 获取某个键对应的所有值
    public List<V> getValues(K key) {
        List<Map.Entry<K, V>> entries = keyIndex.get(key);
        if (entries == null) {
            return List.of();
        }
        return entries.stream().map(Map.Entry::getValue).collect(Collectors.toList());
    }

    // 根据插入索引获取条目
    public Map.Entry<K, V> getEntryByIndex(int index) {
        return entryList.get(index);
    }

    public int size() {
        return entryList.size();
    }
}

这个方案的好处是,每个插入的键值对都是独立的条目,你可以直接通过索引访问某一次插入的内容,适合需要精确跟踪每一步操作的场景。

可选:用第三方库快速实现

如果项目里已经引入了Guava库,那直接用LinkedHashMultimap就可以了——它天生支持保留插入顺序和重复键,用法超级简单:

import com.google.common.collect.LinkedHashMultimap;

public class Demo {
    public static void main(String[] args) {
        LinkedHashMultimap<String, Object> multimap = LinkedHashMultimap.create();
        multimap.put("a", list1);
        multimap.put("e", list2);
        multimap.put("a", list7);

        // 遍历的时候会严格按插入顺序输出所有键值对
        for (Map.Entry<String, Object> entry : multimap.entries()) {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
    }
}

以上几种方案都能满足你的需求,选最适合你项目情况的就行~

内容的提问来源于stack exchange,提问作者Nain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:08:32