1

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.

kwolff7
  • 15
  • 5

3 Answers3

2

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 --;
    }
Community
  • 1
  • 1
Sarath Chandra
  • 1,850
  • 19
  • 40
  • Your code only tells what the values are for the first 5 values. Doesn't actually show the highest value, then the 2nd highest, etc – kwolff7 Apr 18 '16 at 22:38
  • This piece of code is to be used after you do a Collections.sort, using the comparator based approach, as shown in the linked answer. – Sarath Chandra Apr 18 '16 at 22:40
  • I placed above what I tried, it still didn't work, did I do it wrong? – kwolff7 Apr 18 '16 at 22:47
  • There was a small mistake. The `Iterator` was still on the original map, which was not sorted. The `list` collection is the sorted collection. Hence, the iterator should point to `list`. And that solves the problem. – Sarath Chandra Apr 18 '16 at 22:55
0

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.

Gee Bee
  • 1,794
  • 15
  • 17
0

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;
    }

}
Adam Lyu
  • 431
  • 1
  • 5
  • 17
  • [*"What is a raw type and why shouldn't we use it?"*](http://stackoverflow.com/q/2770321/2891664) Your `ValueComparator` will also delete entries with duplicate values. – Radiodef Apr 18 '16 at 23:12