如何按降序对 TreeMap 值进行排序以及如何限制输出?
How to sort TreeMap values in descending order and how to limit the output?
这是我与 Java(一般来说是初学者)一起工作的第三天,我发现在获得我需要的期望输出方面遇到了麻烦。
我正在尝试查找字符串或文本文件中单词出现的频率。到目前为止,我的整个程序都可以正常工作,除了我很难将结果从最频繁的单词输出到更少;此外,我如何将其限制为最常用的 x 个单词。
到目前为止,这是我的代码:
public static void wordOccurrence(String text) {
String[] wordSplit = text.split(" ");
for (int i = 0; i < wordSplit.length; i++) {
Map<String, Integer> occurrence = new TreeMap<>(Collections.reverseOrder());
int Counter = 0;
for (int j = 0; j < wordSplit.length; j++) {
if (wordSplit[i].equals(wordSplit[j])) {
if (j < i)
break;
Counter++;
occurrence.put(wordSplit[j],Counter);
}
}
if (Counter > 1)
System.out.println(occurrence);
}
}
这是我的无序输出:{The=2}{that=2}{to=2}{and=5}{for=2}{as=2}
您正在使用 TreeMap
对您的条目进行排序。 TreeMap
按键而不是值对条目进行排序。
您可以使用 streams
和 LinkedHashMap
来完成该工作:
public static void wordOccurrence(String text) {
String[] wordSplit = text.split(" ");
Map<String, Long> map = Arrays.stream(wordSplit)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<Entry<String, Long>> list = new ArrayList<>(map.entrySet());
list.sort(Entry.comparingByValue(Comparator.reverseOrder()));
Map<String, Long> occurrence = list.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
occurrence.entrySet().forEach(entry -> System.out.println(entry.getKey()+";"+entry.getValue()));
}
或不使用 List
:
public static void wordOccurrence(String text) {
String[] wordSplit = text.split(" ");
Map<String, Long> map = Arrays.stream(wordSplit)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Map<String, Long> occurrence = map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
occurrence.entrySet().forEach(entry -> System.out.println(entry.getKey()+";"+entry.getValue()));
}
如果您只想要顶部的“n”,您可以添加一行 .limit(n)
:
Map<String, Long> occurrence = map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.limit(5)
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
这是我与 Java(一般来说是初学者)一起工作的第三天,我发现在获得我需要的期望输出方面遇到了麻烦。 我正在尝试查找字符串或文本文件中单词出现的频率。到目前为止,我的整个程序都可以正常工作,除了我很难将结果从最频繁的单词输出到更少;此外,我如何将其限制为最常用的 x 个单词。
到目前为止,这是我的代码:
public static void wordOccurrence(String text) {
String[] wordSplit = text.split(" ");
for (int i = 0; i < wordSplit.length; i++) {
Map<String, Integer> occurrence = new TreeMap<>(Collections.reverseOrder());
int Counter = 0;
for (int j = 0; j < wordSplit.length; j++) {
if (wordSplit[i].equals(wordSplit[j])) {
if (j < i)
break;
Counter++;
occurrence.put(wordSplit[j],Counter);
}
}
if (Counter > 1)
System.out.println(occurrence);
}
}
这是我的无序输出:{The=2}{that=2}{to=2}{and=5}{for=2}{as=2}
您正在使用 TreeMap
对您的条目进行排序。 TreeMap
按键而不是值对条目进行排序。
您可以使用 streams
和 LinkedHashMap
来完成该工作:
public static void wordOccurrence(String text) {
String[] wordSplit = text.split(" ");
Map<String, Long> map = Arrays.stream(wordSplit)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<Entry<String, Long>> list = new ArrayList<>(map.entrySet());
list.sort(Entry.comparingByValue(Comparator.reverseOrder()));
Map<String, Long> occurrence = list.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
occurrence.entrySet().forEach(entry -> System.out.println(entry.getKey()+";"+entry.getValue()));
}
或不使用 List
:
public static void wordOccurrence(String text) {
String[] wordSplit = text.split(" ");
Map<String, Long> map = Arrays.stream(wordSplit)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Map<String, Long> occurrence = map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));
occurrence.entrySet().forEach(entry -> System.out.println(entry.getKey()+";"+entry.getValue()));
}
如果您只想要顶部的“n”,您可以添加一行 .limit(n)
:
Map<String, Long> occurrence = map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.limit(5)
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (s1, s2) -> s1, LinkedHashMap::new));