简体   繁体   中英

Get top 10 values in hash map

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 .

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

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

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 .

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
}

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

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);
}
public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        // Initialize map
        System.out.println(getTopKeysWithOccurences(map, 10));
}

public static List<Entry<String,Integer>> getTopKeysWithOccurences(Map mp, int top) {
        List<Entry<String,Double>> results = new ArrayList<>(mp.entrySet());
        Collections.sort(results, (e1,e2) -> e2.getValue() - e1.getValue());
        //Ascending order - e1.getValue() - e2.getValue()
        //Descending order - e2.getValue() - e1.getValue()
        return results.subList(0, top);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM