简体   繁体   English

将HashMap转换为排序的ArrayList

[英]Converting HashMap to Sorted ArrayList

I have a HashMap<String, Integer> containing words along with their frequencies. 我有一个HashMap<String, Integer>包含单词及其频率。 I need to now convert this HashMap into an ArrayList of just the words, discarding of the frequencies, but i also want the ArrayList to be sorted in descending order of words by frequency. 我现在需要将此HashMap转换为仅包含单词的ArrayList ,丢弃频率,但我还希望ArrayList以单词的降序按频率排序

Does anyone know an efficient way to do this? 有人知道这样做的有效方法吗?

HashMap has a convenient method called entrySet() , which lets you access a collection of key-value pairs. HashMap有一个方便的方法,称为entrySet() ,使您可以访问键-值对的集合。 You can use it to construct a List<Map.Entry<String,Integer>> . 您可以使用它来构造List<Map.Entry<String,Integer>>

Now you have something you can sort. 现在,您可以进行排序了。 Use a sort method with a custom comparator, which orders entries with higher frequencies toward the beginning of the list. 使用带有自定义比较器的排序方法,该比较器将频率较高的条目排序到列表的开头。

With a sorted list in hand, all you need to do is walk it, and harvest the words which are now in the proper order. 手头有一个已排序的列表,您所要做的就是走动它,然后按正确的顺序收获单词。

List<Map.Entry<String,Integer>> entries = new ArrayList<Map.Entry<String,Integer>>(
    freqMap.entrySet()
);
Collections.sort(
    entries
,   new Comparator<Map.Entry<String,Integer>>() {
        public int compare(Map.Entry<String,Integer> a, Map.Entry<String,Integer> b) {
            return Integer.compare(b.getValue(), a.getValue());
        }
    }
);
for (Map.Entry<String,Integer> e : entries) {
    // This loop prints entries. You can use the same loop
    // to get the keys from entries, and add it to your target list.
    System.out.println(e.getKey()+":"+e.getValue());
}

Demo. 演示

When using Java 8 you can make use of the Stream API like follows: 使用Java 8时,您可以使用Stream API ,如下所示:

final Map<String, Integer> wordStats = new HashMap<>();
// some dummy data:
wordStats.put("twice", 2);
wordStats.put("thrice", 3);
wordStats.put("once", 1);

final List<String> sortedStats = wordStats.entrySet().stream()
    .sorted(Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()))
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());
    // or to specify the list implementation:
    //.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

// Output
sortedStats.forEach(System.out::println);

Output: 输出:

thrice
twice
once

In Java 8 you can also do this shorter variation of what has been answered 在Java 8中,您还可以对已回答的内容进行这种简短的修改

Ascending order 升序

ArrayList<Map.Entry<String, Integer>> sorted = newArrayList<>(frequencies.entrySet());
sorted.sort(Comparator.comparingInt(Map.Entry::getValue));

Descending order 降序排列

ArrayList<Map.Entry<String, Integer>> sorted = new ArrayList<>(frequencies.entrySet());
sorted.sort(Collections.reverseOrder(Comparator.comparingInt(Map.Entry::getValue)));

You can: 您可以:

  • Put your map in a sortedmap defining your own comparator. 将您的地图放在定义自己的比较器的sortedmap中。
  • Convert the keySet of the sorted map to a list. 将排序后的映射的keySet转换为列表。

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

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