繁体   English   中英

从 Java 中的 HashMap 中获取关键对象

[英]Get key object out of a HashMap in Java

我想在 Java 中检索 HashMap 中键的原始对象,最好的方法是什么?

例如

HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
Integer keyObj = new Integer(10);
Integer valueObj = new Integer(100);

// And add maybe 1 million other key value pairs here
//... later in the code, if I want to retrieve the valueObj, given the value of a key to be 10
Integer retrievedValueObj = map.get(10);

//is there a way to retrieve the original keyObj object with value 10 from map?

基本上,用户可以在这里查询key的任意值,只针对key对象,10只是一个例子。 有人评论说,“你已经有了 x 对象,你为什么要得到它?” 嗯,这和说“你已经有了价值对象,你为什么要得到它?”是一样的。 这就是 HashMap 数据结构、存储和检索的目的。

检索值对象很容易,但似乎没有多少人知道如何检索关键对象。 好像很多人不明白我为什么要达到10的目的,问为什么? 为什么不只是值 10。这只是一个大大简化的模型。

好吧,让我提供一点背景信息。 keyObj 是另一个数据结构中的数据,我需要这个原始密钥对象的确切引用。 说,有一个所有键值的链表,如果我想删除链表中的特定节点。

我不仅对值“10”感兴趣,而且对内存位置感兴趣,即该“10”对象在 Java 中的引用。 内存中可能有很多“10”。 但那个确切的对象是我想要检索的。

下面的迭代器方法答案给出了 O(n) 方法。 但我正在寻找的是给定键值的键 OBJECT 的 O(1) 检索。

我能想到的一种方法是将关键对象也存储在值中,例如

class KeyAndValue {
     public Integer key;
     public Integer value;
     public KeyAndValue(Integer key, Integer value) {
         this.key = key;
         this.value = value;
     }
}

map<Integer, keyAndValueL> map = new map<Integer, keyAndValueL>();
Integer x = new Integer(10);
map.add(x, new KeyAndValue(x, 100));

//then I can retrieve the reference of x, given value of key 10
Integer newKeyObj = map.get(10).key;

但这种方法使用更多内存,对我来说看起来像是一种黑客攻击。 我想知道 Java 中是否有更优雅的方式。

一种类似但更通用的方法是将“键+值”存储为条目而不是封装在另一个类中。 例子:

    Map<Integer, Entry<Integer, Integer>> map = new HashMap<Integer, Entry<Integer, Integer>>();
    Integer x = new Integer(10);
    map.put(x, new AbstractMap.SimpleEntry<Integer, Integer>(x, 100));

    //then I can retrieve the reference of x, given value of key 10
    Entry<Integer, Integer> keyObj = map.get(10);

尝试这个

        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        Integer keyObj = new Integer(10);
        Integer valueObj = new Integer(100);
        map.put(keyObj, valueObj);
        Set<Integer> keys = map.keySet();
        Iterator<Integer> iterator = keys.iterator();
        while(iterator.hasNext()){
            Integer x = iterator.next();
            if(map.get(x) == 100)
                System.out.println("key is "+ x);
        }

正如您在问题中提到的,您可以将键 + 值对象存储为“作为值”。

您正在实施的是享元模式的变体。

这是使用每个托管对象到自身的映射最容易实现的:

Map<T, T> cache = new HashMap<>();

对于您遇到的每个对象:

T obj; // comes from somewhere
obj = cache.computeIfAbsent(obj, v -> obj); // reuse, or add to cache if not found

这具有 O(1) 时间复杂度,并且对于如此管理的每个对象仅使用一个额外的对象引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM