java 从 HashMap 中查找对象键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5248964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:13:37  来源:igfitidea点击:

Find a object key from a HashMap

javacollections

提问by Amit

I have a HashMap having key as my own object and key as ArrayList of String. Is there a way to get the key object from the map which is equal to another object without iterating the map. Please note that my object has implemented equals & hashcode. And it only uses 2 attribute of the class to compare. The another object which I am trying to find in the keys of the map has those 2 attribute equal but the other attributes may be different in the key of the map.

我有一个 HashMap,其键是我自己的对象,键是 String 的 ArrayList。有没有办法从地图中获取与另一个对象相等的关键对象,而无需迭代地图。请注意,我的对象已经实现了 equals & hashcode。它只使用类的 2 个属性进行比较。我试图在地图的键中找到的另一个对象的这两个属性相等,但其他属性在地图的键中可能不同。

//The actual map
private HashMap<FileDetail, ArrayList<String>> map = new HashMap<FileDetail, ArrayList<String>>();
//object to search in above map without iteration.
FileDetail file = some object;

I want to get the reference of the "file" object in the keys of the map.

我想在地图的键中获取“文件”对象的引用。

回答by krtek

No you can't do that. HashMapare supposed to work the other way : you have the key, you're looking for the object.

不,你不能那样做。HashMap应该以另一种方式工作:你有钥匙,你正在寻找对象。

If you have an object and you want to find the key, there's probably something wrong in your logic and your looking in a wrong direction to solve your problem.

如果您有一个对象并且您想找到钥匙,那么您的逻辑可能有问题并且您寻找解决问题的方向错误。

回答by dogbane

If you don't want to iterate over the keySet, then you can use Guava'sBiMap. A biMap has an inverse view which is another bimap containing reversed keys and values. This is how you would use it:

如果您不想遍历 keySet,则可以使用Guava 的BiMap。biMap 有一个反向视图,它是另一个包含反向键和值的 bimap。这是你将如何使用它:

BiMap<FileDetail, ArrayList<String>> biMap = HashBiMap.create();

//object to search in above map without iteration.
FileDetail file = some object;

FileDetail key = biMap.inverse().get(biMap.get(file));

回答by Philipp Wendler

If you really need to do this without iteration over the keySet (e.g. because the map is very large), I suggest storing both the key and the list as values in the map. Either create some specific class encapsulating both, or use a simple pair class. The map would look like:

如果您真的需要在不迭代 keySet 的情况下执行此操作(例如,因为地图非常大),我建议将键和列表作为值存储在地图中。要么创建一些封装两者的特定类,要么使用简单的配对类。地图看起来像:

Map<FileDetail, Pair<FileDetail, List<String>>>

If you can't change the type of the map, you can use a second Map<FileDetail, FileDetail>where key and value are always the same objects.

如果您无法更改地图的类型,则可以使用第二个Map<FileDetail, FileDetail>,其中键和值始终是相同的对象。

回答by Michael K. Eidson

This question is five years old, but I had the same question just today, and found this page. I thought I'd share the solution I decided upon using, which is not described in any of the existing answers and avoids iterating over all the keys in the map. (Please be gentle; this is my first posting on SO. It's tough finding questions I can answer that don't already have answers. Moreover, every question I've had to date has already been asked on SO. I've been using SO for years, with no ability to comment or vote on answers.)

这个问题已经五年了,但我今天也有同样的问题,并找到了这个页面。我想我会分享我决定使用的解决方案,该解决方案在任何现有答案中都没有描述,并避免迭代地图中的所有键。(请保持温和;这是我第一次在 SO 上发帖。很难找到我可以回答但还没有答案的问题。此外,我迄今为止遇到的每个问题都已经在 SO 上被问过了。我一直在使用多年来一直如此,无法对答案发表评论或投票。)

As has been stated already, maps are designed so that when you have a key, you look up a value. That being the case, the answer is to use the key also as the value, so that when you perform a lookup using an arbitrary key, which equalsyour original key but is not necessarily ==to it, you get back the original key. The issue then, is how to get what you originally intended to be the value.

正如已经说过的,映射的设计是为了当你有一个键时,你可以查找一个值。在这种情况下,答案是也使用键作为值,这样当您使用任意键执行查找时,equals您的原始键但不一定==是它的原始键,您可以取回原始键。那么问题是如何获得您最初打算成为的价值。

My solution depends on having control of the class used for the key, and control of the map, with the ability to redefine them, which appears to be the case for the OP. In the OP's example, this would be control of the FileDetailclass and of the private mapvariable. Assuming such control, the FileDetailclass would be modified to contain a member variable of type ArrayList<String>, which for my sample code below I'll call list, with associated setter and getter methods. For the private mapvariable, it would be defined thusly:

我的解决方案取决于对用于键的类的控制和对地图的控制,以及重新定义它们的能力,这似乎是 OP 的情况。在 OP 的示例中,这将是对FileDetail类和私有map变量的控制。假设有这样的控制,FileDetail该类将被修改为包含类型ArrayList<String>为的成员变量,对于我下面的示例代码,我将调用它list,并带有相关的 setter 和 getter 方法。对于私有map变量,它将这样定义:

private HashMap<FileDetail, FileDetail> map = new HashMap<>();

Now, when you want to puta new ArrayList<String>object in the map, assigned to a specific FileDetailkey, you assign the ArrayList<String>object to the FileDetail's ArrayList<String>member variable instead, and then place the FileDetailobject in the map.

现在,当您想要将映射中put的新ArrayList<String>对象分配给特定FileDetail键时,您可以将该ArrayList<String>对象分配给FileDetailArrayList<String>成员变量,然后将该FileDetail对象放入map.

public void putInMap(FileDetail fd, ArrayList<String> al) {
    // Ignoring null conditions for simplicity...
    fd.setList(al);
    map.put(fd, fd);
}

Later, when you get some arbitrary FileDetailobject (one that equalsthe key but isn't necessarily ==to it), and you want the associated key, it's a matter of doing a normal lookup:

稍后,当您获得一些任意FileDetail对象(一个是equals键但不一定==是它的对象),并且您想要关联的键时,只需进行正常查找即可:

FileDetail otherFd = getArbitraryFileDetail();
FileDetail originalKeyFd = map.get(otherFd);

And to get the associated ArrayList<String>after having performed the above:

ArrayList<String>在执行上述操作后获取关联:

ArrayList<String> al = originalKeyFd.getList();

Certainly this all hinges on the implementations of the equalsand hashCodemethods of the FileDetailclass, but the OP already had those methods defined as desired.

当然,这一切都取决于类的equalshashCode方法的实现FileDetail,但是 OP 已经根据需要定义了这些方法。

Hope this helps anyone who, like me, comes to this page with a similar situation.

希望这可以帮助像我一样以类似情况来到此页面的任何人。

回答by Raghunath

We get the key object from Hashmap without iterating the keyset of HashMap by converting keyset to ArrayList. This is a simple example:

我们通过将keyset转换为ArrayList,从Hashmap中获取key对象,而无需迭代HashMap的keyset。这是一个简单的例子:

//Creating hashmap
HashMap<String, String> map = new HashMap<String, String>();

//Adding elements into the map  
map.put("1", "Amit");
map.put("2", "Ananth");
map.put("3", "Sunil");

//Get the list from keyset
ArrayList myKeyList = new ArrayList(map.keySet());

//object to search in above map without iteration.
String myobj = "3";
System.out.println(myKeyList.get(myKeyList.indexOf(myobj)));

回答by M. Jessup

You are likely looking for a Bidirectional Map, Apache Commons Collectionsincludes this as part of the library (im sure there are other imeplementations as well.) A bidirectional map, just as the name implies, is a map but written so as to make looking up by key or by value efficient.

您可能正在寻找双向映射,Apache Commons Collections 将其作为库的一部分包含在内(我确定还有其他实现。)双向映射,顾名思义,是一种映射,但编写的目的是为了使按键或按值高效。

回答by Adam Batkin

In Java, HashMapassociates a key with a value, not the other way around.

在 Java 中,HashMap将键与值相关联,而不是相反。

You can retrieve a Setof all of the keys using HashMap.keySet(), or alternatively iterate over all of the entries using HashMap.entrySet():

您可以使用 检索Set所有键中的一个HashMap.keySet(),或者使用迭代所有条目HashMap.entrySet()

for (Entry <FileDetail, ArrayList<String>> entry : map.entrySet()) {
    FileDetail key = entry.getKey();
    if (shouldProcess(key)) {
        ArrayList<String> list = entry.getValue();
        processList(list);
    }
}