kwolff7
kwolff7

Reputation: 15

Finding the Key from Value in Map

So I am having a bit of trouble understanding how to do this. I am building a word counter in Java using Map<String, Integer> where a word is the String and the amount of times that word was said in a .txt document is Integer. This is all working great...but I am trying to develop a part where it will display at the bottom what the top 5 results are ---> what the top 5 map.values() are.

The problem I have run into is after I find the value, I can't get the String with it.

Any suggestions would be very helpful to me.

Upvotes: 1

Views: 63

Answers (3)

Adam Lyu
Adam Lyu

Reputation: 461

I suggest you to override Comparator and build your Map constructor based on it. Code is showed below:

class ValueComparator implements Comparator {
    Map map;

    public ValueComparator(Map map) {
        this.map = map;
    }

    public int compare(Object keyA, Object keyB) {
        Comparable valueA = (Comparable) map.get(keyA);
        Comparable valueB = (Comparable) map.get(keyB);
        return valueB.compareTo(valueA);
    }
}

public class YourClass{
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("a", 10);
        map.put("b", 30);
        map.put("c", 50);
        map.put("d", 40);
        map.put("e", 20);
        System.out.println(map);

        Map sortedMap = sortByValue(map);
        System.out.println(sortedMap);
    }

    public static Map sortByValue(Map unsortedMap) {
        Map sortedMap = new TreeMap(new ValueComparator(unsortedMap));
        sortedMap.putAll(unsortedMap);
        return sortedMap;
    }

}

Upvotes: 0

Sarath Chandra
Sarath Chandra

Reputation: 1878

You need to use the Map.Entry<String, Integer> to get the pair of the key and value.

The values() method returns only values, whereas the keySet() method returns only the keys.

Firstly, you should sort your map, based on values, to get the top five results. The straightforward approach uses a Comparator. See the answer here for more.

Then you simply get the first five entries of the map.getEntrySet(). It would be easier to use an Iterator for this.

UPDATE:

    Set<Entry<String, Integer>> set = wordCount.entrySet();
    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
    Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
        public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
            return o2.getValue().compareTo(o1.getValue());
        }
    });

    int topResults = 5;
    Iterator<Entry<String, Integer>> iter = list.iterator(); //refer the sorted collection
    while (iter.hasNext() && topResults > 0 ) {
        Map.Entry<String, Integer> entry = iter.next();
        System.out.println(entry.getKey() + "->" + entry.getValue());
        topResults --;
    }

Upvotes: 2

Gee Bee
Gee Bee

Reputation: 1794

a) Iterate over the map, this way you have both keys and values accessible:

for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    // ...
}

b) build a second map for reverse lookup, e.g. Map - note that this is likely not a good idea here as you may have duplicate keys (same number for different words)

c) consider using a bidimap - this is a map which you can query both by key and by value.

Upvotes: 0

Related Questions