如何对用Formatter生成的单词统计表格按出现次数排序?
按单词出现次数排序统计结果的解决方案
你的需求完全可行,核心问题在于HashMap本身是无序的,要实现按出现次数排序,只需将统计好的键值对转成有序集合后再处理即可。下面提供两种实现方式:
方式一:List+Comparator排序(兼容Java 7及以上)
修改processWholeFile方法的遍历输出部分,先把Map条目转为List,再通过自定义比较器按次数排序:
public void processWholeFile() { Map<String, Integer> stringMap = new HashMap<String, Integer>(); Formatter formatter = new Formatter(); List<String> lines = readFile(); String string = String.join(" ", lines); String[] arr = string.split(" "); for (String s : arr) { stringMap.put(s, stringMap.getOrDefault(s, 0) + 1); // 简化原有的存在性判断逻辑 } formatter.format("%20s %20s\n\n", "Word", "Occurence"); // 将Map条目转为List并按出现次数降序排序(升序则调换o2和o1的位置) List<Map.Entry<String, Integer>> sortedEntries = new ArrayList<>(stringMap.entrySet()); Collections.sort(sortedEntries, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); // 遍历排序后的条目输出 for (Map.Entry<String, Integer> mapEntry : sortedEntries) { if (mapEntry.getKey().startsWith("1")) { // 简化原有的字符串截取判断 formatter.format("%20s %20s\n", mapEntry.getKey(), mapEntry.getValue()); } else { formatter.format("%20s %15s\n", mapEntry.getKey(), mapEntry.getValue()); } } System.out.println(formatter); }
方式二:Stream API排序(Java 8及以上)
利用Java 8的Stream可以更简洁地完成排序逻辑:
public void processWholeFile() { Map<String, Integer> stringMap = new HashMap<String, Integer>(); Formatter formatter = new Formatter(); List<String> lines = readFile(); String string = String.join(" ", lines); String[] arr = string.split(" "); for (String s : arr) { stringMap.put(s, stringMap.getOrDefault(s, 0) + 1); } formatter.format("%20s %20s\n\n", "Word", "Occurence"); // 通过Stream按出现次数降序排序并输出 stringMap.entrySet() .stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .forEach(mapEntry -> { if (mapEntry.getKey().startsWith("1")) { formatter.format("%20s %20s\n", mapEntry.getKey(), mapEntry.getValue()); } else { formatter.format("%20s %15s\n", mapEntry.getKey(), mapEntry.getValue()); } }); System.out.println(formatter); }
额外优化点
- 用
map.getOrDefault(s, 0) + 1替代了原有的containsKey判断,代码更简洁 - 用
startsWith("1")替代substring(0,1).equals("1"),逻辑更直观且效率更高
内容的提问来源于stack exchange,提问作者Gahatma
相关产品推荐
相关产品推荐

