简体   繁体   English

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

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

I would like to retrieve the original object of a key in a HashMap in Java, what is the best way to do it?我想在 Java 中检索 HashMap 中键的原始对象,最好的方法是什么?

For example例如

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?

Basically, the user can query any value of key here just for the key object, 10 is just an example.基本上,用户可以在这里查询key的任意值,只针对key对象,10只是一个例子。 Some comment say, "you already have the x object, why do you want to get it?"有人评论说,“你已经有了 x 对象,你为什么要得到它?” Well, this is the same as saying "you already have the value object, why do you want to get it?"嗯,这和说“你已经有了价值对象,你为什么要得到它?”是一样的。 That is the purpose for the HashMap data structure, store and retrieval.这就是 HashMap 数据结构、存储和检索的目的。

Retrieving a value object is easy but it seems no many people know how to retrieve the key object.检索值对象很容易,但似乎没有多少人知道如何检索关键对象。 It seems like many people don't get why I want to achieve the object of 10 and ask why?好像很多人不明白我为什么要达到10的目的,问为什么? why not just value 10. This is just a greatly simplified model.为什么不只是值 10。这只是一个大大简化的模型。

Well, let me give a little bit context.好吧,让我提供一点背景信息。 The keyObj is data in another data structure and I need the exact reference of this original key object. keyObj 是另一个数据结构中的数据,我需要这个原始密钥对象的确切引用。 Say, there is a linked list of all the key values, and if I want to remove a particular node in the linked list.说,有一个所有键值的链表,如果我想删除链表中的特定节点。

I am not only interested in the value "10", but also the memory location, ie the reference in Java of that "10" object.我不仅对值“10”感兴趣,而且对内存位置感兴趣,即该“10”对象在 Java 中的引用。 There could be many "10"'s in memory.内存中可能有很多“10”。 But that exact object is what I want to retrieve.但那个确切的对象是我想要检索的。

The iterator approach answer below give an O(n) approach.下面的迭代器方法答案给出了 O(n) 方法。 But what I am looking for is an O(1) retrieval of the key OBJECT given the key value.但我正在寻找的是给定键值的键 OBJECT 的 O(1) 检索。

One way I can think of is to store the key object in value as well, like我能想到的一种方法是将关键对象也存储在值中,例如

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;

but this approach uses more memory and looks like a hack to me.但这种方法使用更多内存,对我来说看起来像是一种黑客攻击。 I am wondering if there is a more elegant way in Java.我想知道 Java 中是否有更优雅的方式。

A similar aproach but more generic is to store the "key + value" as an Entry instead of encapsule in another class.一种类似但更通用的方法是将“键+值”存储为条目而不是封装在另一个类中。 Example:例子:

    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);

try this尝试这个

        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);
        }

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

What you are implementing is a variant of the flyweight pattern .您正在实施的是享元模式的变体。

This is easiest implemented using a Map of every managed object to itself:这是使用每个托管对象到自身的映射最容易实现的:

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

And for every object you encounter:对于您遇到的每个对象:

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

This has O(1) time complexity and uses only one extra object reference for each object so managed.这具有 O(1) 时间复杂度,并且对于如此管理的每个对象仅使用一个额外的对象引用。

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

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