2017-08-10 15 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>這將是必要的。