简体   繁体   中英

Efficient way to get the most used keys in a HashMap - Java

I have a HashMap where the key is a word and the value is a number of occurrences of that string in a text. Now I'd like to reduce this HashMap to only 15 most used words (with greatest numbers of occurrences). Do you have any idea to do this efficiently?

Using an array instead of ArrayList as suggested by Pindatjuh could be better,

public class HashTest {
        public static void main(String[] args) {
            class hmComp implements Comparator<Map.Entry<String,Integer>> {
                public int compare(Entry<String, Integer> o1,
                        Entry<String, Integer> o2) {
                    return o2.getValue() - o1.getValue();
                }
            }
            HashMap<String, Integer> hm = new HashMap<String, Integer>();
            Random rand = new Random();
            for (int i = 0; i < 26; i++) {
                hm.put("Word" +i, rand.nextInt(100));
            }
            ArrayList list = new ArrayList( hm.entrySet() );
            Collections.sort(list, new hmComp() );
            for ( int i = 0  ; i < 15 ; i++ ) {
                System.out.println( list.get(i) );
            }

        }
    }

EDIT reversed sorting order

One way I think of to tackle this, but it's probably not the most efficient, is:

  • Create an array of hashMap.entrySet().toArray(new Entry[]{}) .
  • Sort this using Arrays.sort , create your own Comparator which will compare only on Entry.getValue() (which casts it to an Integer). Make it order descending, ie most/highest first, less/lowest latest.
  • Iterate over the sorted array and break when you've reached the 15th value.
Map<String, Integer> map = new HashMap<String, Integer>();

    // --- Put entries into map here ---

    // Get a list of the entries in the map
    List<Map.Entry<String, Integer>> list = new Vector<Map.Entry<String, Integer>>(map.entrySet());

    // Sort the list using an annonymous inner class implementing Comparator for the compare method
    java.util.Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
        public int compare(Map.Entry<String, Integer> entry, Map.Entry<String, Integer> entry1)
        {
            // Return 0 for a match, -1 for less than and +1 for more then
            return (entry.getValue().equals(entry1.getValue()) ? 0 : (entry.getValue() > entry1.getValue() ? 1 : -1));
        }
    });

    // Clear the map
    map.clear();

    // Copy back the entries now in order
    for (Map.Entry<String, Integer> entry: list)
    {
        map.put(entry.getKey(), entry.getValue());
    }

Use first 15 entries of map. Or modify last 4 lines to put only 15 entries into map

您可以使用LinkedHashMap并删除最近最少使用的项目。

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