如何对Java Map词频统计结果按出现次数升序输出?
按单词出现次数升序输出词频的解决方案
你的代码已经完成了词频统计的核心逻辑,但因为使用了无序的HashMap,输出结果无法按次数排序。以下是修改后的实现,直接解决按出现次数升序输出的需求:
修改后的完整代码
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class Analyser { public static void main(String[] args) throws IOException { // 用try-with-resources自动管理流资源,避免泄漏 try (BufferedReader br = new BufferedReader(new FileReader("src/txt.txt"))) { String line; Map<String, Long> counts = new HashMap<>(); while ((line = br.readLine()) != null) { String[] words = line.split("[\\s.;,?:!()\"]+"); for (String word : words) { word = word.trim(); if (word.length() > 0) { // 用merge简化计数逻辑,替代原有的containsKey判断 counts.merge(word, 1L, Long::sum); } } } // 按单词出现次数升序排序后输出 counts.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .forEach(entry -> System.out.println(entry.getKey() + " : " + entry.getValue())); } } }
关键修改说明
- 排序实现:通过Stream API将Map条目转为流,用
Map.Entry.comparingByValue()直接指定按值(次数)升序排序。如果需要降序,只需在sorted后追加.reversed()。 - 简化计数逻辑:用
Map.merge()方法一行完成单词计数更新,替代原有的containsKey判断,代码更简洁高效。 - 资源优化:使用
try-with-resources语法,无需手动调用br.close(),JVM会自动关闭流,避免资源泄漏。
非Stream API的传统实现方式
如果不想用Stream,也可以用集合排序的方式:
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; // ... 统计逻辑部分不变 // 将Map条目转为List进行排序 List<Map.Entry<String, Long>> entryList = new ArrayList<>(counts.entrySet()); // 按次数升序排序 Collections.sort(entryList, Comparator.comparingLong(Map.Entry::getValue)); // 遍历输出排序后的结果 for (Map.Entry<String, Long> entry : entryList) { System.out.println(entry.getKey() + " : " + entry.getValue()); }
内容的提问来源于stack exchange,提问作者justjenn
相关产品推荐
相关产品推荐

