2011-11-09 124 views
19

我正在尋找一種方法來存儲鍵值對。我需要查找是雙向的,但同時我需要爲同一個密鑰存儲多個值。換句話說,像BidiMap這樣的東西,但是對於每個鍵都可以有多個值。例如,它需要能夠保存像「s1」 - > 1,「s2」 - > 1,「s3」 - > 2這樣的對,並且我需要能夠將值映射到每個鍵,並且對於每個值,獲取與其關聯的所有密鑰。Java中的雙向多值映射

+3

您提到每個鍵需要多個值,但在您的示例中,您沒有具有多個值的鍵,而是具有兩個鍵的值。你應該澄清一點。如果你的例子適合你的問題,你會得到更好的答案;-) – pushy

+0

http://www.jguru.com/faq/view.jsp?EID=1317828在這裏你可以找到如何創建multimap – maks

+0

@pushy,同樣的問題,如果我反轉地圖,並保留整數作爲鍵而不是值,我會得到一對多的映射。無論如何,感謝您的更正。 :) –

回答

19

所以你需要支持多對多的關係嗎?最近你可以得到GuavaMultimap就像@Mechkov寫的 - 但更具體地說Multimap組合Multimaps.invertFrom。 「BiMultimap」尚未實現,但在Google Guava庫中請求此功能的an issue

在這一點上,你有幾種選擇:

  1. 如果你的「BiMultimap」將不可變不變 - 使用Multimaps.invertFromImmutableMultimap/ImmutableListMultimap/ImmutableSetMultimap(每個theese三個具有不同的收集保存的值)。某些代碼(例如,從應用程序開發我取,使用Enum S和Sets.immutableEnumSet):

    ​​
  2. 如果你真的想你Multimap之要修改,這將是難以維持兩個K-> V與V-> K變體,除非您每次需要修改kToVMultimap並致電invertFrom(並且使該副本不可修改,以確保您不小心不會修改vToKMultimap什麼不會更新kToVMultimap)。這不是最佳的,但應該在這種情況下。

  3. (不是你的情況可能是,提到獎金):BiMap接口和實現類具有.inverse()方法,給出了從BiMap<K, V>BiMap<V, K>視圖和自身biMap.inverse().inverse()後。如果我之前提到的this issue完成了,它可能會有類似的東西。

  4. (編輯2016年10月)您也可以使用new graph API這將是目前在Guava 20

    作爲一個整體,共同的。圖形支持的以下品種圖:

    • 向圖
    • 無向圖
    • 節點和/或邊緣與相關聯的值(權重,標籤等)
    • 圖表,做/不允許自循環
    • 圖表,做/不允許平行的邊緣(與平行邊緣圖有時被稱爲多重圖)
    • 圖的節點/邊緣插入順序,分類或無序
-1

希望我把你的右

class A { 
    long id; 
    List<B> bs; 
} 

class B { 
    long id; 
    List<A> as; 
} 
2

出了什麼問題有兩個地圖,鍵 - >值,值 - >鍵?

+3

我認爲保留相同數據的兩個副本會更容易出錯。無論如何,在我看過的所有藏品之後,我開始認爲這是最好的解決方案。 –

+2

只需爲保持同步的地圖創建一個包裝。 – Stefan

+10

我不喜歡這個答案認可的方法。這有很多可能的錯誤,包括重新發明輪子,沿途編寫自己的錯誤,線程安全等。 – bacar

-3

谷歌的Guava MultiMap實現是我用於這些目的。

Map<Key Collection<Values>> 

其中Collection可以是一個ArrayList例如。它允許存儲在一個集合中的多個值映射到一個鍵。 希望這有助於!

+0

不是雙向的。 – Stefan

1

使用谷歌番石榴,我們可以如下編寫原始BiMulitMap。

import java.util.Collection; 

import com.google.common.collect.ArrayListMultimap; 
import com.google.common.collect.Multimap; 

public class BiMultiMap<K,V> { 

    Multimap<K, V> keyToValue = ArrayListMultimap.create(); 
    Multimap<V, K> valueToKey = ArrayListMultimap.create(); 

    public void putForce(K key, V value) { 
     keyToValue.put(key, value); 
     valueToKey.put(value, key); 
    } 

    public void put(K key, V value) { 
     Collection<V> oldValue = keyToValue.get(key); 
     if (oldValue.contains(value) == false) { 
      keyToValue.put(key, value); 
      valueToKey.put(value, key); 
     } 
    } 

    public Collection<V> getValue(K key) { 
     return keyToValue.get(key); 
    } 

    public Collection<K> getKey(V value) { 
     return valueToKey.get(value); 
    } 

    @Override 
    public String toString() { 
     return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]"; 
    } 

} 

希望這將有助於雙向多地圖的一些基本需求。 請注意K和V需要正確實施hascode和equals方法