Как отсортировать значения TreeMap в порядке убывания и как ограничить вывод? - PullRequest
0 голосов
/ 09 июля 2020

это мой третий день работы с 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}

1 Ответ

0 голосов
/ 09 июля 2020

Вы используете 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));
...