2014-09-29 66 views
1

我需要創建一個包含3列的地圖:2個鍵和1個值。所以每個值都會包含2個不同類型的鍵,並且可以使用任何一個來獲取。但我的問題是,HashMap/Map只支持1個鍵和1個值。有沒有辦法創建類似Map<Key1, Key2, Value>而不是Map<Key, Value>?所以Value可以通過使用其Key1Key2來獲取。帶有多個鍵的Java地圖

我很抱歉,如果它是一個重複或壞的問題,但我找不到類似的堆棧溢出。

P.S:我不想創建2個地圖:Map<Key1, Value>Map<Key2, Value>也沒有創建嵌套地圖我正在尋找一個多鍵表,只是像上面這樣。

+1

可能重複:有一個數據結構,它就像一個多重映射,但接受複製關鍵?](http://stackoverflow.com/questions/1968003/java-is-there-a-data-structure-that-works-like-a-multimap-but-accepts-duplicate) – 2014-09-29 22:37:53

+0

我不相信有一個現有的數據結構可以做你想做的事情。你將不得不寫你自己的。 – 2014-09-29 22:43:13

+0

番石榴的['Multimap'](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html)本質上是一個'Map >'你也可以檢查出來['BiMap'](http://docs.guava-libraries.googlecode.com/git-history/master/javadoc/com/google/common/collect/BiMap.html)。 – 2014-09-29 22:43:29

回答

1

只是存儲的值的兩倍:

Map<Object, Value> map = new HashMap<>(); 
map.put(key1, someValue); 
map.put(key2, someValue); 

的事情是,它並不重要,關鍵是什麼類型的,所以用一個通用的綁定,允許兩種密鑰類型 - Object是好的。

注意,參數類型Map#get()方法只是Object無論如何,所以從查找觀點有具有獨立的地圖沒有值(密鑰類型僅適用於put()相關)。

+0

好的,我只會做2張地圖。謝謝 – Victor2748 2014-09-29 23:22:09

+1

只要不需要特定的'Key1'和'Key2'泛型類型變量的類型安全性,這是一個很好的解決方案。 – 2014-09-29 23:26:26

+0

@victor我會**不**使用兩個地圖。不得不查看這兩個映射是浪費你的時間,代碼和CPU週期,AFAICT沒有好處。這是重要的地圖的價值類型。請注意,Map的'get'方法的參數類型是'Object'! – Bohemian 2014-09-29 23:41:22

2

您可能將不得不編寫一個類似地圖類的自定義實現來實現這一點。我同意上面的@William Price,最簡單的實現是簡單地封裝兩個Map實例。請小心使用Map接口,因爲它們依賴equals()和hashCode()作爲您打算在合約中打破的密鑰標識。

2

寫班級符合你的要求自己:

import java.util.HashMap; 
import java.util.Map; 

public class MMap<Key, OtherKey, Value> { 

    private final Map<Key, Value> map = new HashMap<>(); 

    private final Map<OtherKey, Value> otherMap = new HashMap<>(); 

    public void put(Key key, OtherKey otherKey, Value value) { 
     if (key != null) { // you can change this, if you want accept null. 
      map.put(key, value); 
     } 
     if (otherKey != null) { 
      otherMap.put(otherKey, value); 
     } 
    } 

    public Value get(Key key, OtherKey otherKey) { 
     if (map.containsKey(key) && otherMap.containsKey(otherKey)) { 
      if (map.get(key).equals(otherMap.get(otherKey))) { 
       return map.get(key); 
      } else { 
       throw new AssertionError("Collision. Implement your logic."); 
      } 
     } else if (map.containsKey(key)) { 
      return map.get(key); 
     } else if (otherMap.containsKey(otherKey)) { 
      return otherMap.get(otherKey); 
     } else { 
      return null; // or some optional. 
     } 
    } 

    public Value getByKey(Key key) { 
     return get(key, null); 
    } 

    public Value getByOtherKey(OtherKey otherKey) { 
     return get(null, otherKey); 
    } 
} 
+0

哇感謝的人! – Victor2748 2014-09-30 02:56:02