从 hashMap 中取出 10 个具有最高值的字符串

Taking 10 Strings with highest values from hashMap

我想将网站标题中的所有单词保存到文件中。然后我想取 10 个最常用的单词并将它们保存到另一个文件中。 所以我已经保存到文件中了。 但我一直在寻找这 10 个词。我的代码只查找 1 个最常用的词,仅此而已。肯定有比我做过的更好的方法来做到这一点。如果你给我一些提示,我将非常感激。我在这里浏览了最热门的主题,但所有主题都是关于寻找一个最常用的词。

List<String> mostRepeatedWords = new ArrayList<>();
Set<Map.Entry<String, Integer>> entrySet = wordsMap.entrySet();
int max = 0;
for (int i = 0; i < entrySet.size(); i++) {
    for (Map.Entry<String, Integer> entry : entrySet) {   //here I'm looking for the word with the highest value in the map
        if (entry.getValue() > max) {
            max = entry.getValue();
            }
     }
     for (Object o : wordsMap.keySet()) {     //here I write this word to a list
         if (wordsMap.get(o).equals(max)) {
             mostRepeatedWords.add(o.toString());
         }
    }
}

@编辑 这是我计算字数的方法:

while (currentLine != null) {
    String[] words = currentLine.toLowerCase().split(" ");

    for (String word : words) {
        if (!wordsMap.containsKey(word) && word.length() > 3) {
            wordsMap.put(word, 1);
        } else if (word.length() > 3) {
            int value = wordsMap.get(word);
            value++;
            wordsMap.replace(word, value);
        }
    }
    currentLine = reader.readLine();
}

您可以将最常出现的单词保存到一个数组中,然后检查您找到的下一个单词是否已存在于该数组中。然后搜索该数组中不存在的下一个最常用词。

这个适合你吗?

首先,根据出现频率倒序排列地图的单词(即键)。

List<String> words = mapOfWords.entrySet().stream()
        .sorted(Entry.comparingByValue(Comparator.reverseOrder()))
        .limit(10)
        .map(Entry::getKey)
        .collect(Collectors.toList());

然后使用这些键以递减频率打印前 10 个单词。

for (String word : words) {
    System.out.println(word + " " + mapOfWords.get(word));
}

另一种不使用流的更传统的方法如下:

测试数据

Map<String, Integer> mapOfWords =
        Map.of("A", 10, "B", 3, "C", 8, "D", 9);

创建地图条目列表

List<Entry<String, Integer>> mapEntries =
        new ArrayList<>(mapOfWords.entrySet());

定义一个 Comparator 以根据频率对条目进行排序

Comparator<Entry<String, Integer>> comp = new Comparator<>() {
    @Override
    public int compare(Entry<String, Integer> e1,
            Entry<String, Integer> e2) {
            Objects.requireNonNull(e1);
            Objects.requireNonNull(e2);
        // notice e2 and e1 order is reversed to sort in descending order.
        return Integer.compare(e2.getValue(), e1.getValue());
    }
};

上面的内容等同于 Map.Entry class

中定义的以下内容
Comparator<Entry<String,Integer>> comp =
   Entry.comparingByValue(Comparator.reverseOrder());

现在用任一比较器对列表进行排序。

mapEntries.sort(comp);

现在打印条目列表。如果超过 10 个,您将需要放入限制计数器或使用 mapEntries.subList(0, 10) 作为 for loop.

的目标
for (Entry<?,?> e : mapEntries) {
     System.out.println(e);
}

假设您已经有了您的频率图,它可能类似于:

Map<String,Integer> wordsMap = Map.of( "foo", 2,
                                       "bar", 7,
                                       "baz", 5,
                                       "doo", 9,
                                       "tot", 2,
                                       "gee", 12);

您可以创建另一个地图,即前十名地图(在我的演示中,前三名下方),方法是按相反顺序按值对地图进行排序并将其限制为前十个条目

Map<String,Integer> topThree = wordsMap.entrySet()
                                       .stream()
                                       .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
                                       .limit(3)
                                       .collect(Collectors.toMap(
                                          Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,LinkedHashMap::new));

System.out.println(topThree);

//{gee=12, doo=9, bar=7}