2017-08-10 18 views
7

我有多个包含key = value字符串对的文件。这些文件之间的密钥相同,但值不同。每个文件可以有1000个这样的对。Java - 指向同一个密钥的多个hashmaps

我想将每个文件存储在一个单独的散列图中,即map<KeyString, ValueString>,所以如果有五个文件,那么将会有五个hashmaps。

要避免在每个散列映射中重复键,是否有可能让每个映射引用同一个键?请注意,一旦密钥添加到地图中,它将不会被删除。

我认为在flyweight模式下将第一个文件作为'base',这个基础将是键/值的内在集合。其他剩余的文件将是外在的一组值,但我不知道如何将值与基本(内部)键关联而不需要重复键值?

我接受了一个更简单/更好的方法。

+0

谢谢你的建议。 我决定使用字符串池,无论是使用intern()还是手动使用池(如果Java默认已经实现了,则根本无法使用)。 再次感谢。 – Timegate

回答

1

读完钥匙后,您可以使用String.intern()。 调用时,它的作用可以是:

  • 字符串添加到内部池,如果不存在的话;
  • 如果它已经存在,则返回池中的等效字符串。

String#intern Javadoc

+0

不错!不知道! – xenteros

+0

@kewne plz不要...这将是一个恶梦调试,以防万一出现问题。一般'intern'非常不鼓励 – Eugene

+1

@Eugene我同意'intern'应该用在特殊情况下,但这似乎是它。为什么这里不合适? – kewne

1

首先,我没有看到存储String键的多个实例的问题。 5 HashMap s * 1000键是一个非常小的数字,并且不应该有内存问题。也就是说,如果你仍然想避免重复String,你可以创建第一个HashMap,然后你就可以得到与其他HashMap完全相同的密钥。

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

你可以写这样的事情来填充第二HashMap

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

当然,你必须找到第一个地图的每个key第二张地图的相应值。如果密钥在输入文件中没有以相同的顺序存储,这可能需要一些初步的排序步骤。

+0

或者一个'Enum'作为密钥......以防万一他真的想要那个 – Eugene

2

我可以考虑一个更简单的方法。代替Map<String, String>认为Map<String, List<String>或直接MultiMap<String, String>来自guava

如果每个关键是在每个文件都有价值,你可以在第0指数,在第一个指数存储从第二个从第一个文件值等

如果它不会工作,我建议Collection<Map<String, String> ,所以你可以遍历你的Map。然后,如果要将值增加到Map之一,请遍历所有keySet,如果其中一个包含该键,则只需放入从此keySet返回的对象。

其他解决方案将有一个HashSet键已被放置。这会更有效率。

0

也许你可以持有static Map<>到您的钥匙映射到独特Integers,并使用这些Integer S为关键,以你的地图?

喜欢的东西:

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>这将是必要的。