有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java多个哈希映射指向同一个键

我有多个包含key=value字符串对的文件。文件之间的键相同,但值不同。每个文件可以有1000多个这样的对

我想将每个文件存储在一个单独的hashmap中,即map<KeyString, ValueString>,因此如果有五个文件,那么将有五个hashmap

为了避免在每个hashmap中重复键,是否可以让每个映射引用相同的键?请注意,一旦将关键点添加到地图中,它将不会被删除

我考虑将第一个文件设为“基”,就像在flyweight模式中一样,这个基将是一组固有的键/值。剩下的其他文件将是外部值集,但我不知道如何在不复制键的情况下将这些值关联回基本(内部)键

我愿意采用更简单/更好的方法


共 (4) 个答案

  1. # 1 楼答案

    也许您可以持有static Map<>将密钥映射到唯一的Integers,并使用这些Integer作为映射的密钥

    比如:

    class KeySharedMap<K,V> {
        // The next key to use. Using Atomics for the auto-increment.
        static final AtomicInteger next = new AtomicInteger(0);
        // Static mapping of keys to unique Integers.
        static final ConcurrentMap<Object,Integer> keys = new ConcurrentHashMap<>();
        // The map indexed by Integer from the `keys`.
        Map<Integer, V> map = new HashMap<>();
    
    
        public V get(Object key) {
            return map.get(keys.get(key));
        }
    
        public V put(Object key, V value) {
            // Associate a unique integer for each unique key.
            keys.computeIfAbsent(key,x -> next.getAndIncrement());
            // Put it in my map.
            return map.put(keys.get(key),value);
        }
    }
    

    是的,我知道这里没有使用K,但我怀疑如果您希望实现Map<K,V>,这是必要的

  2. # 2 楼答案

    我可以考虑一种更简单的方法。不要让Map<String, String>想到Map<String, List<String>或者直接从guava想到MultiMap<String, String>

    如果每个键都在每个文件中并且都有值,则可以将第一个文件的值存储在第0个索引中,将第二个文件的值存储在第1个索引中,以此类推

    如果它不起作用,我推荐一个Collection<Map<String, String>,这样你就可以迭代你的Map。然后当你想给其中一个Map添加值时,就遍历所有的keySet,如果其中一个包含那个键,就用这个keySet返回的对象放进去

    另一个解决方案是拥有HashSet个已经放置的密钥。这样会更有效率

  3. # 3 楼答案

    读入键后,可以使用String.intern()。 调用时,它会执行以下操作之一:

    • 如果该字符串不存在,则将其添加到内部池中
    • 从池中返回等效字符串(如果已存在)

    String#intern Javadoc

  4. # 4 楼答案

    首先,我不认为存储字符串键的多个实例有什么问题。5HashMaps*1000个键是一个非常小的数字,您不应该有内存问题

    也就是说,如果您仍然希望避免重复String,可以创建第一个HashMap,然后为其他HashMap创建完全相同的键

    例如,假设map1是第一个HashMap,并且已经填充了第一个文件的内容

    您可以编写如下内容来填充第二个HashMap

    for (String key : map1.keySet()) {
        map2.put (key, someValue);
    } 
    

    当然,您必须为第一个映射的每个key找到第二个映射的对应值。如果键在输入文件中的存储顺序不同,这可能需要一些初步的排序步骤