简体   繁体   English

如何从hashmap中获取5个最高值?

[英]How to get 5 highest values from a hashmap?

I have a Hashmap that links a zipcodes stored as keys and population stored as values in a hashmap. 我有一个Hashmap链接存储为键的zipcodes和作为值存储在hashmap中的填充。

The hashmap contains around 33k entries. hashmap包含大约33k个条目。

I'm trying to get the 5 highest population values from 5 zip codes and print out the 5 zip codes ASSOCIATED with the 5 highest population, but I'm having trouble understanding the algorithm of how to do it. 我试图从5个邮政编码中获取5个最高人口值,并打印出与5个最高人口相关联的5个邮政编码,但我无法理解如何做到这一点的算法。

If it was just one, its easy but the 5 restriction is giving me some trouble. 如果它只是一个,它很容易,但5限制给我一些麻烦。

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 thats it. 我知道将5个值存储在一个int数组中,我有一个计数器来确定它们中何时存储了5个,但就是这样。

Thanks 谢谢

    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++)
        {

        }
    }

}

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. 但33k元素是一个数字,其中排序的O(n * log(n))复杂性可能已经具有显着的性能影响。

One apporach would be to employ the PriorityQueue that nr4bt already mentioned (I wrote this snippet while he answered). 一个apporach将是使用nr4bt已经提到过的PriorityQueue(我回答时写了这个片段)。 It basically inserts all elements into a PriorityQueue that is sorted according to the values of the map entries. 它基本上将所有元素插入到PriorityQueue中,该PriorityQueue根据映射条目的值进行排序。

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

Try this, using standard methods and assuming that the population count is stored as Integer s in the HashMap : 尝试使用标准方法并假设人口计数在HashMap存储为Integer

List<Integer> list = new ArrayList<Integer>(zipCodePop.values());
Collections.sort(list, Collections.reverseOrder());
List<Integer> top5 = list.subList(0, 5);

public class CheckHighiestValue { public static void main(String... s) { public class CheckHighiestValue {public static void main(String ... s){

    HashMap<String, Integer> map = new HashMap<String, Integer>();

    map.put("first", 10000);
    map.put("second", 20000);
    map.put("third", 300);
    map.put("fourth", 800012);
    map.put("fifth", 5000);
    map.put("sixth", 30012);
    map.put("seventh", 1234);
    map.put("eighth", 45321);
    map.put("nineth", 5678);

    Set<Entry<String, Integer>> set = map.entrySet();

    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(
            set);

    Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

        @Override
        public int compare(Entry<String, Integer> o1,
                Entry<String, Integer> o2) {

            return o2.getValue().compareTo(o1.getValue());
        }

    });
    System.out.println(list.subList(0, 5));
}

} }

PriorityQueue would help too, and also a nice topic about how to get top k from a list, you can check this link PriorityQueue也会有所帮助,也是一个关于如何从列表中获得前k个的好主题,您可以查看此链接

PriorityQueue<Integer> p = new PriorityQueue<Integer>(5);

int[] a = new int[]{3,5,10,1,23,42,66,1333,545,110};

for (int i : a){
    p.add(i);
    if (p.size() > 5){
        p.poll();
    }
}

//output will be highest 5, [42, 66, 110, 1333, 545]

You can have O(n log(k)) time complexity // k is your top value count. 你可以有O(n log(k))时间复杂度// k是你的最高值。

This is something i made and hopefully provides you something that you want to use. 这是我做的,希望能为您提供您想要使用的东西。

public class TopsCollection { 

private static Map<String, Integer> collectors = new HashMap<>();

public TopsCollection() {
}

public void add(String playerName, int score) {
    collectors.put(playerName, score);
}

public void clearCollectors() {
    synchronized (collectors) {
        collectors.clear();
    }
}

public List<Map.Entry<String, Integer>> getTops() {
    return collectors.entrySet().stream().sorted(comparing(Map.Entry::getValue, reverseOrder())).limit(5).collect(toList());
}

public int getTopByName(String name) {
    for (int i = 0; i < getTops().size(); i++) {
        if (getTops().get(i).getKey().contains(name)) {
            return i;
        }
    }
    return 0;
}

getTopByName allows you to get the top place of the specified name. getTopByName允许您获取指定名称的顶部位置。

How would you do this without a computer, with just a piece of paper and a pencil? 如果没有电脑,只用一张纸和一支铅笔,你会怎么做? Pretend you had a stack of index cards that had numbers on them, and it was your job to find the 5 highest numbers. 假装你有一堆索引卡上有数字,找到5个最高数字是你的工作。 How would you do that? 你会怎么做? Write down steps that somebody else could follow to achieve the goal, and when you have those steps written out, you'll have an algorithm that you can start thinking about implementing with code. 写下其他人可以遵循的步骤来实现目标,当你写完这些步骤时,你将有一个算法,你可以开始考虑用代码实现。

You say that a single maximum is easy, so do it exactly like you would with a single maximum, but keep track of the five maximums instead. 你说一个单一的最大值很容易,所以它就像你用一个最大值一样,但是要跟踪五个最大值。 An array of maximums might be helpful here. 这里有一组最大值可能会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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