Get top 10 values in hash map

2020-06-03 09:46发布

问题:

I am trying to figure out how could I get the top 10 values from the HashMap. I was initially trying to use the TreeMap and have it sort by value and then take the first 10 values however it seems that that is not the option, as TreeMap sorts by key.

I want to still be able to know which keys have the highest values, the K, V of the map are String, Integer.

回答1:

Maybe you should implement the Comparable Interface to your value objects stored in the hashmap. Then you can create a array list of all values:

List<YourValueType> l = new ArrayList<YourValueType>(hashmap.values());
Collection.sort(l);
l = l.subList(0,10);

Regards



回答2:

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Testing {

    public static void main(String[] args) {

        HashMap<String,Double> map = new HashMap<String,Double>();
        ValueComparator bvc =  new ValueComparator(map);
        TreeMap<String,Double> sorted_map = new TreeMap<String,Double>(bvc);

        map.put("A",99.5);
        map.put("B",67.4);
        map.put("C",67.4);
        map.put("D",67.3);

        System.out.println("unsorted map: "+map);

        sorted_map.putAll(map);

        System.out.println("results: "+sorted_map);
    }
}

class ValueComparator implements Comparator<String> {

    Map<String, Double> base;
    public ValueComparator(Map<String, Double> base) {
        this.base = base;
    }

    // Note: this comparator imposes orderings that are inconsistent with equals.    
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}


回答3:

I am afraid you'll have to iterate over the entire map. Heap is a commonly-used data structure for finding top K elements, as explained in this book.



回答4:

If you are trying to get the 10 highest values of the map (assuming the values are numeric or at least implementing Comparable) then try this:

List list = new ArrayList(hashMap.values());
Collections.sort(list);
for(int i=0; i<10; i++) {
   // Deal with your value
}


回答5:

Let's assume you have a Map, but this example can work for any type of

Map<String, String> m = yourMethodToGetYourMap();
List<String> c = new ArrayList<String>(m.values());
Collections.sort(c);
for(int i=0 ; i< 10; ++i) {
    System.out.println(i + " rank is " + c.get(i)); 
}


回答6:

I base my answer in this one from sk2212

First you need to implement a descending comparator:

class EntryComparator implements Comparator<Entry<String,Integer>> {

    /**
     * Implements descending order.
     */
    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        if (o1.getValue() < o2.getValue()) {
            return 1;
        } else if (o1.getValue() > o2.getValue()) {
            return -1;
        }
        return 0;
    }

}

Then you can use it in a method such as this one for the attribute "hashmap":

public List<Entry<String,Integer>> getTopKeysWithOccurences(int top) {
    List<Entry<String,Integer>> results = new ArrayList<>(hashmap.entrySet());
    Collections.sort(results, new EntryComparator());
    return results.subList(0, top);
}