2014-09-29 62 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