从HashMap中查找对象键

时间:2011-03-09 16:36:10

标签: java collections

我有一个HashMap,它将key作为我自己的对象,键作为String的ArrayList。有没有办法从地图中获取等于另一个对象的关键对象而不迭代地图。请注意我的对象实现了等于&哈希码。它只使用类的2个属性进行比较。我试图在地图的键中找到的另一个对象具有相同的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;

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

7 个答案:

答案 0 :(得分:4)

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

如果你有一个对象,并且想要找到密钥,那么你的逻辑中可能存在一些问题,并且你找错了方向来解决你的问题。

答案 1 :(得分:2)

如果您不想迭代keySet,则可以使用Guava's 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));

答案 2 :(得分:0)

您可能正在寻找双向地图,Apache Commons Collections将此作为库的一部分包含在内(我确定还有其他的imeplement。)双向地图,顾名思义,是一张地图,但是已经写好了以便通过关键或高效率来查找。

答案 3 :(得分:0)

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

您可以使用HashMap.keySet()检索所有密钥的Set,或者使用HashMap.entrySet()迭代所有条目:

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

答案 4 :(得分:0)

我们从Hashmap获取密钥对象,而不通过将keyset转换为ArrayList来迭代HashMap的密钥集。这是一个简单的例子:

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

答案 5 :(得分:0)

如果你真的需要在没有迭代keySet的情况下这样做(例如因为地图非常大),我建议将键和列表存储为地图中的值。要么创建一个封装两者的特定类,要么使用简单的对类。地图看起来像:

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

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

答案 6 :(得分:0)

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

正如已经说明的那样,地图的设计使得当你有一把钥匙时,你会查找一个值。在这种情况下,答案是使用密钥作为值,这样当您使用任意密钥执行查找时,equals原始密钥但不一定是==,你拿回原来的钥匙。那么问题就是如何获得你原本打算成为价值的东西。

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

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

现在,如果您希望put地图中的ArrayList<String>新对象分配给特定的FileDetail密钥,则可以将ArrayList<String>对象分配给{{ 1}}&#39; FileDetail成员变量,然后将ArrayList<String>对象放在FileDetail中。

map

稍后,当您获得一些任意public void putInMap(FileDetail fd, ArrayList<String> al) { // Ignoring null conditions for simplicity... fd.setList(al); map.put(fd, fd); } 个对象(一个FileDetail密钥但不一定equals的对象),并且您需要关联的密钥,它& #39;进行正常查找的问题:

==

在执行上述操作后获取关联的FileDetail otherFd = getArbitraryFileDetail(); FileDetail originalKeyFd = map.get(otherFd);

ArrayList<String>

当然这一切都取决于ArrayList<String> al = originalKeyFd.getList(); 类的equalshashCode方法的实现,但OP已经根据需要定义了这些方法。

希望这有助于像我这样的人来到这个类似情况的页面。