javahashmapmax

How to get the 5 highest values from a hashmap


I have a Hashmap that links zipcodes stored as keys and population stored as values in a hashmap.

The hashmap contains around 33k entries.

I'm trying to get the 5 highest population values and print out the 5 zip codes associated with those 5 highest populations, but I'm having trouble understanding how to do it.

If it was just one, it would be easy, but the 5-element restriction is giving me some trouble.

I know to store the 5 values in an int array and I have a counter to determine when 5 of them are stored, but that's it.

int populatedCounter = 0;

int[] populatedZip = new int[5];

it = zipCodePop.entrySet().iterator();
while (it.hasNext())
{
    Map.Entry pairs = (Map.Entry)it.next();
    for (int i = 0; i < populatedZip.length; i++)
    {
    }
}

Solution

  • Putting the entries of such a set into a list and sorting it is one option. But 33k elements is a number where the O(n*log(n)) complexity of sorting might already have a noticable performance impact.

    One apporach would be to employ the PriorityQueue that nr4bt already mentioned (I wrote this snippet while he answered). It basically inserts all elements into a PriorityQueue that is sorted according to the values of the map entries.

    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.PriorityQueue;
    
    public class GreatestOfMap
    {
        public static void main(String[] args)
        {
            Map<String, Integer> map = new HashMap<String, Integer>();
    
            map.put("zip000", 1234);
            map.put("zip001", 2345);
            map.put("zip002", 3456);
            map.put("zip003", 4567);
            map.put("zip004", 5678);
            map.put("zip005", 6789);
            map.put("zip006", 123);
            map.put("zip007", 234);
            map.put("zip008", 456);
            map.put("zip009", 567);
            map.put("zip010", 7890);
            map.put("zip011", 678);
            map.put("zip012", 789);
            map.put("zip013", 890);
    
            int n = 5;
            List<Entry<String, Integer>> greatest = findGreatest(map, 5);
            System.out.println("Top "+n+" entries:");
            for (Entry<String, Integer> entry : greatest)
            {
                System.out.println(entry);
            }
        }
    
        private static <K, V extends Comparable<? super V>> List<Entry<K, V>> 
            findGreatest(Map<K, V> map, int n)
        {
            Comparator<? super Entry<K, V>> comparator = 
                new Comparator<Entry<K, V>>()
            {
                @Override
                public int compare(Entry<K, V> e0, Entry<K, V> e1)
                {
                    V v0 = e0.getValue();
                    V v1 = e1.getValue();
                    return v0.compareTo(v1);
                }
            };
            PriorityQueue<Entry<K, V>> highest = 
                new PriorityQueue<Entry<K,V>>(n, comparator);
            for (Entry<K, V> entry : map.entrySet())
            {
                highest.offer(entry);
                while (highest.size() > n)
                {
                    highest.poll();
                }
            }
    
            List<Entry<K, V>> result = new ArrayList<Map.Entry<K,V>>();
            while (highest.size() > 0)
            {
                result.add(highest.poll());
            }
            return result;
        }
    }