如何使用列表作为值从映射中获取键

3

我正在使用Java集合来制作类似标签的东西。我使用列表作为值创建了一个映射。

我能否通过从列表中搜索单词来获取键?我该如何做到这一点?

Map<String, List<String>> map = new HashMap<String, List<String>>();    
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();

list1.add("mammal");
list1.add("cute");

list2.add("mammal");
list2.add("big");

map.put("cat", list1);
map.put("dog", list2);

尝试使用map.get函数(请参见http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get(java.lang.Object))。 - Peter_James
2
一个相同的值可以被映射到多个键。你会如何处理这种情况?也许你正在寻找一个BiMap(查看Guava collections API)。 - Alexis C.
我认为你使用Map的方式没有必要。我更建议使用“反向索引”设计地图:http://en.wikipedia.org/wiki/Inverted_index 。这样,你将动物存储在一个转储集合中,同时创建有效的结构来将标签映射到动物。 - manzur
4个回答

3
如果我理解正确的话,您想在列表中存储对应值时获取密钥?当然,您可以始终使用Map接口的values()方法获取所有这些列表,然后遍历它们。但是,如果有第二个映射,您可以使用标签作为键,并存储携带此标签的所有条目的列表。对于大型数据集,这样做可能会更加高效。

这是正确的答案。Larry Wall曾经说过,遍历哈希表的键就像用装满子弹的Uzi枪殴打某人一样。 - Christoffer Hammarström

3
for (Entry<String, List<String>> entry : map.entrySet()) {
    if (entry.getValue().contains(animalYouSearch)) {
        System.out.println(animalYouSearch + " is in " + entry.getKey());
    }
}

搜索“哺乳动物”的输出结果:

猫中有哺乳动物

狗中有哺乳动物


谢谢,我觉得这就是我想要的 :) - osek

0

这并没有什么“神奇”的方法,你需要在值中进行搜索,然后报告正确的键。

例如:

String str = "cute";
List<String> matchingKeys = map.entrySet().stream().filter( e -> e.getValue().contains(str))
  .map(e -> e.getKey()).collect(Collectors.toList());

但是您可能希望以不同的方式存储数据,即“特征”列表作为键,动物名称作为值。


如果他想切换键和值,并将列表用作键,那么他应该使用某种不可变列表,比如Guava,因为可变的键类型是危险的 - Tom

0
如果您想检索一组标签,请使用此方法:
public Set<String> findMatchingKeys(Map<String, List<String>> map, String word){
        Set<String> tags = new HashSet<String>();
        for(Map.Entry<String,List<String> > mapEntry : map.entrySet()){
            if(mapEntry.getValue().contains(word))
                tags.add(mapEntry.getKey());
        }
        return tags;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接