有没有办法从"地图"中获取密钥(或整个条目)?

maa*_*nus 8 java map

有什么办法如何让从钥匙(或整个条目)HashMap(或其他合适的Map)有效

在有人说之前,我从不需要它:我做到了.我有这样的循环

for (long i=0; i<1e12; ++i) {
    Key key = new Key(i);
    Value value = map.get(key);
    if (something(key, value)) list.add(key);
}
Run Code Online (Sandbox Code Playgroud)

key如果我可以用list.add(key)类似的东西 代替list.add(map.getKey(key))(新的实例有资格用于GC),我的不必要的记忆可以保存.虽然它们是相同的,但重用旧实例会节省内存.

我知道我可以将钥匙嵌入价值或使用番石榴Interner; 两者都有帮助,但两者都需要一些记忆.


解决一些误解的评论:如果效率没有问题,可以采取以下措施

Key getKeyFromMap(Key key, Map<Key, ?> map) {
    for (Key key2 : map.keySet()) {
        if (key.equals(key2)) return key2;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

接受的答案中描述的最有效的解决方案:

public static <K, V> K getKey(K key, HashMap<K, V> map) {
    final Entry<K, V> entry = map.getEntry(key);
    return entry==null ? null : entry.getKey();
}
Run Code Online (Sandbox Code Playgroud)

问题是必须放入package java.util它,因为它使用包私有方法.使用这种方法可能很危险,但在我的"一次运行"用例中没有问题.

Tom*_*son 8

为了做到这一点,你准备承诺多少邪恶?

Map界面不允许您检索密钥或条目.Set界面也没有.HashMap公共界面也不是.

但是HashMap封装接口不会(在Sun JDK,至少).看看源代码 ; 在第355行,有一个方法被调用getEntry,如下所示:

  /**
   * Returns the entry associated with the specified key in the
   * HashMap.  Returns null if the HashMap contains no mapping
   * for the key.
   */
  final Entry<K,V> getEntry(Object key) {
Run Code Online (Sandbox Code Playgroud)

我相信这正是你所需要的.你可以用反射来调用它,或者将你自己的类偷偷带入java.util包中.Java维护者将来可以采用这种方法,它可能不会出现在所有平台上,但是如果你准备好嗤之以鼻并承担风险,这是一个简单的解决方案.

  • 新签名是`Node <K,V> getNode(int hash,Object key)` - 至少在JDK1.8.0_74(Oracle)中. (2认同)