从 HashMap 中查找对象键

发布于 2024-10-20 19:58:47 字数 454 浏览 1 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

茶底世界 2024-10-27 19:58:47

不,你不能那样做。 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.

叫思念不要吵 2024-10-27 19:58:47

如果您不想迭代 keySet,则可以使用 Guava 的 < a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/BiMap.html" rel="nofollow">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));

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:

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));
×眷恋的温暖 2024-10-27 19:58:47

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

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

如果无法更改地图的类型,则可以使用第二个 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:

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.

对你的占有欲 2024-10-27 19:58:47

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

正如已经说过的,地图的设计是为了当你有一个键时,你可以查找一个值。既然如此,答案就是将键也用作值,这样当您使用任意键执行查找时,它等于您的原始键,但不一定== 到它,你就得到了原来的密钥。那么问题是如何得到你最初想要的值。

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

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

现在,当您想要在地图中 put 一个新的 ArrayList 对象时,分配给特定的 FileDetail 键,您将 ArrayList 对象分配给 FileDetailArrayList< /code> 成员变量,然后将 FileDetail 对象放入 map 中。

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

稍后,当您获得任意 FileDetail 对象(一个 等于 键但不一定 == 的对象)时,您想要关联的键,这是进行正常查找的问题:

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

并在执行上述操作后获取关联的 ArrayList

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

当然,这一切都取决于 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 private map variable. Assuming such control, the FileDetail class 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 map variable, it would be defined thusly:

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

Now, when you want to put a new ArrayList<String> object in the map, assigned to a specific FileDetail key, you assign the ArrayList<String> object to the FileDetail's ArrayList<String> member variable instead, and then place the FileDetail object in the 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 FileDetail object (one that equals the key but isn't necessarily == to it), and you want the associated key, it's a matter of doing a normal lookup:

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

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

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

Certainly this all hinges on the implementations of the equals and hashCode methods of the FileDetail 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.

心房敞 2024-10-27 19:58:47

您可能正在寻找双向地图,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.

等你爱我 2024-10-27 19:58:47

在 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() :

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

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

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

for (Entry <FileDetail, ArrayList<String>> entry : map.entrySet()) {
    FileDetail key = entry.getKey();
    if (shouldProcess(key)) {
        ArrayList<String> list = entry.getValue();
        processList(list);
    }
}
流绪微梦 2024-10-27 19:58:47

我们从Hashmap中获取key对象,而不需要通过将keyset转换为ArrayList来迭代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)));

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

//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)));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文