有什么方法可以有效地从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);
}
和我的 key
不必要地占用内存,如果我可以用 list.add(map.getKey) 替换
(新实例将有资格进行 GC)。 虽然它们是相等的,但重用旧实例会节省内存。list.add(key)
(key))
我知道我可以将键嵌入到值中或使用 Guava 的 Interner
;两者都有帮助,但都会消耗一些内存。
为了解决一些误解的评论:如果效率没问题,下面会做
Key getKeyFromMap(Key key, Map<Key, ?> map) {
for (Key key2 : map.keySet()) {
if (key.equals(key2)) return key2;
}
return null;
}
已接受的答案中描述的最有效的解决方案:
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();
}
问题是它必须放在 package java.util
中,因为它使用包私有(private)方法。使用这种方法可能很危险,但在我的“运行一次”用例中没有问题。
最佳答案
为了做到这一点,你准备犯下多少罪恶?
Map
接口(interface)不允许您检索键或条目。 Set
接口(interface)也没有。 HashMap
的公共(public)接口(interface)也没有。
但是HashMap
的package 接口(interface)可以(至少在Sun JDK 中)。看看the source code ;在第 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) {
我相信这正是您所需要的。您可以通过反射调用它,或者将您自己的类偷偷放入 java.util
包中。 Java 维护者将来可能会取消此方法,它可能不会出现在所有平台上,但如果您准备好忍住并承担风险,这是一个简单的解决方案。
关于java - 有什么方法可以从 `Map` 获取 key (或整个条目)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12769606/