如何从地图中检索关键对象?

时间:2014-02-21 06:01:17

标签: java collections

获取同一个A类的两个实例,称为foo和bar,其中:

foo != bar
foo.equals(bar) == true

换句话说,foo和bar是不同的实例,但具有相同的哈希码。现在取一个名为“map”的Map<A,B>实例,其中foo是map中的一个键。是否可以使用bar从Map中检索foo?目前我遍历键集并比较每个键但有更快的方法吗? Map中似乎没有任何方法可以检索密钥。

我愿意尝试任何实现Map的数据结构,或者像地图一样工作。

为什么我要这样做?我试图避免保留不必要的实例。一旦我找到foo,我就可以释放吧。

提前致谢...

5 个答案:

答案 0 :(得分:1)

您可以使用Apache Commons Collections ™。它有双向地图BidiMap 这些表示键可以查找值的映射,值可以轻松查找键。

BidiMap bidi = new TreeBidiMap();
bidi.put("SIX", "6");
bidi.get("SIX");  // returns "6"
bidi.getKey("6");  // returns "SIX"
bidi.removeValue("6");  // removes the mapping
BidiMap inverse = bidi.inverseBidiMap();  // returns a map with keys and values swapped

另见

答案 1 :(得分:1)

HashMap确实有一个方法来检索条目,但它是包私有的。我不确定为什么说实话不公开。我不认为它暴露任何东西。当然,你可以用反射来称呼它。

Map<String, String> map = new HashMap<String, String>();
map.put(new String("hello"), "world!");

Method method = (
    HashMap.class.getDeclaredMethod("getEntry", Object.class)
);
method.setAccessible(true);

@SuppressWarnings("unchecked")
Map.Entry<String, String> entry = (Map.Entry<String, String>)(
    method.invoke(map, new String("hello"))
);

System.out.println(entry.toString().replace("=", " ")); // hello world

反射可能使它在您描述的场景中没用,但我想这可能对其他人有用。我不建议使用它。

答案 2 :(得分:1)

仅使用现有地图查找重复项似乎不够。使用第二张地图,放置(键,键)对。然后:

  • map.get(key)==如果密钥不存在则为null
  • map.get(key)== firstObjectAllocated否则

答案 3 :(得分:0)

您可以参考HashMap

的源代码

如果基于您的实施: foo.hashCode() == bar.hashCode()foo.equals(bar)

然后,是的,您可以直接获取密钥foo的值 map.get(bar)


更新:抱歉在你之前误解了你的问题 如果你想保留密钥,为什么你不要只是保持密钥缓存。然后检索密钥是哈希树映射,应该很快。

HashMap<K,V> map = new HashMap<K,V>();
HashMap<K,K> cacheKeys = new HashMap<K,K>();
cacheKeys.put(foo,foo);
map.put(foo,value);

//now you have var bar; you could retrieve the cached key
bar = cacheKeys.get(bar);//this will make bar = foo; the real bar will be gc
//then get the value 
val = map.get(bar);

答案 4 :(得分:0)

这种方式可能更快。

   Iterator<A> mapKeyIterator=map.keySet().iterator();
    while (mapKeyIterator.hasNext()){
        A key;
        if((key=mapKeyIterator.next()).equals(bar)) {
            return key;
        }
    }