3

I am making something like tags using Java collections. I made a map using list as a value.

Can I get a key searching by words from list? How I can do that?

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);
Alexis C.
  • 82,826
  • 18
  • 154
  • 166
osek
  • 47
  • 1
  • 5
  • Try the map.get function (See http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get(java.lang.Object) – Peter_James May 30 '15 at 12:47
  • 2
    A same value can be mapped to multiple keys. How would you handle that case? Maybe you are looking for a `BiMap` (look into the Guava collections API). – Alexis C. May 30 '15 at 12:49
  • I see no reason to use Map in the way you do. I would better suggest to design "reverted index" with the map http://en.wikipedia.org/wiki/Inverted_index . In that way you store animals in a dump collections, while you make efficient structure to map from tag to an animal. – manzur May 30 '15 at 12:58

4 Answers4

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

Output if you search for "mammal":

mammal is in cat

mammal is in dog

Stéphane Bruckert
  • 18,252
  • 10
  • 81
  • 113
3

If I understand you correctly, you want to obtain the key given one of the value in the list stored as the corresponding value? Of course, you can always get all these lists using the values() method of the Map interface and then iterate over those. However, how about having a second map where you use your tags as keys and store a list of all the entries carrying this tag? For large data sets, this will probably perform better.

niceguy
  • 92
  • 4
0

There is no 'magic' way for it, you need to search inside the values and then report the correct key.

For example:

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

But you probably want to store your data other way arround, the list of "features" being the key, and the value the animal name.

Zielu
  • 7,144
  • 4
  • 26
  • 39
  • If he wants to switch key and value and use the list as the key instead, then he should use some kind of an immutable list, like in [Guava](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html), because a mutable key type is [dangerous](http://stackoverflow.com/questions/9973596/arraylist-as-key-in-hashmap#9973694). – Tom May 30 '15 at 13:14
0

If you want to retrieve set of tags, use this method:

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;
    }
mkuligowski
  • 1,375
  • 1
  • 13
  • 24