从 HashMap 中查找对象键
我有一个 HashMap,其键作为我自己的对象,键作为 String 的 ArrayList。有没有一种方法可以从映射中获取与另一个对象相同的关键对象,而无需迭代映射。请注意,我的对象已实现 equals &哈希码。并且它只使用类的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 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.
//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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不,你不能那样做。
HashMap
应该以另一种方式工作:你有密钥,你正在寻找对象。如果你有一个物体并且你想找到钥匙,那么你的逻辑可能有问题,而且你解决问题的方向也有问题。
No you can't do that.
HashMap
are supposed to work the other way : you have the key, you're looking for the object.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.
如果您不想迭代 keySet,则可以使用 Guava 的 < a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html" rel="nofollow">BiMap。 biMap 有一个反向视图,它是另一个包含反向键和值的 bimap。您将这样使用它:
If you don't want to iterate over the keySet, then you can use Guava's BiMap. A biMap has an inverse view which is another bimap containing reversed keys and values. This is how you would use it:
如果您确实需要在不迭代 keySet 的情况下执行此操作(例如,因为地图非常大),我建议将键和列表都存储为地图中的值。要么创建一些封装两者的特定类,要么使用简单的配对类。地图如下所示:
如果无法更改地图的类型,则可以使用第二个
Map
,其中键和值始终是相同的对象。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:
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.这个问题已经有五年了,但我今天也有同样的问题,并找到了这个页面。我想我应该分享我决定使用的解决方案,该解决方案在任何现有答案中都没有描述,并且避免了迭代地图中的所有键。 (请温柔点;这是我在 SO 上的第一篇文章。很难找到我可以回答但还没有答案的问题。此外,迄今为止我遇到的每个问题都已经在 SO 上被问过。我一直在使用多年来,没有能力对答案发表评论或投票。)
正如已经说过的,地图的设计是为了当你有一个键时,你可以查找一个值。既然如此,答案就是将键也用作值,这样当您使用任意键执行查找时,它
等于
您的原始键,但不一定==
到它,你就得到了原来的密钥。那么问题是如何得到你最初想要的值。我的解决方案取决于对用于键的类的控制和对地图的控制,并能够重新定义它们,这似乎是OP的情况。在OP的示例中,这将是对
FileDetail
类和私有map
变量的控制。假设进行这样的控制,FileDetail
类将被修改为包含ArrayList
类型的成员变量,对于下面的示例代码,我将其称为list
,以及相关的 setter 和 getter 方法。对于私有map
变量,它的定义如下:现在,当您想要在地图中
put
一个新的ArrayList
对象时,分配给特定的FileDetail
键,您将ArrayList
对象分配给FileDetail
的ArrayList< /code> 成员变量,然后将
FileDetail
对象放入map
中。稍后,当您获得任意
FileDetail
对象(一个等于
键但不一定==
的对象)时,您想要关联的键,这是进行正常查找的问题:并在执行上述操作后获取关联的
ArrayList
:当然,这一切都取决于
equals
的实现FileDetail
类的 code> 和hashCode
方法,但 OP 已经根据需要定义了这些方法。希望这对像我一样来到此页面遇到类似情况的人有所帮助。
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.)
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
equals
your 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.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
FileDetail
class and of the privatemap
variable. Assuming such control, theFileDetail
class would be modified to contain a member variable of typeArrayList<String>
, which for my sample code below I'll calllist
, with associated setter and getter methods. For the privatemap
variable, it would be defined thusly:Now, when you want to
put
a newArrayList<String>
object in the map, assigned to a specificFileDetail
key, you assign theArrayList<String>
object to theFileDetail
'sArrayList<String>
member variable instead, and then place theFileDetail
object in themap
.Later, when you get some arbitrary
FileDetail
object (one thatequals
the key but isn't necessarily==
to it), and you want the associated key, it's a matter of doing a normal lookup:And to get the associated
ArrayList<String>
after having performed the above:Certainly this all hinges on the implementations of the
equals
andhashCode
methods of theFileDetail
class, but the OP already had those methods defined as desired.Hope this helps anyone who, like me, comes to this page with a similar situation.
您可能正在寻找双向地图,Apache Commons Collections 将此作为库的一部分包含在内(我确信还有其他实现。)双向映射,顾名思义,是一个映射,但编写的目的是为了通过键或值高效查找。
You are likely looking for a Bidirectional Map, Apache Commons Collections includes 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.
在 Java 中,
HashMap
将键与值关联起来,而不是相反。您可以使用
HashMap.keySet()
,或者使用HashMap.keySet()
迭代所有条目。 oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html#entrySet%28%29" rel="nofollow">HashMap.entrySet()
:In Java,
HashMap
associates a key with a value, not the other way around.You can retrieve a
Set
of all of the keys usingHashMap.keySet()
, or alternatively iterate over all of the entries usingHashMap.entrySet()
:我们从Hashmap中获取key对象,而不需要通过将keyset转换为ArrayList来迭代HashMap的keyset。这是一个简单的例子:
We get the key object from Hashmap without iterating the keyset of HashMap by converting keyset to ArrayList. This is a simple example: