Сортировать коллекцию по частоте потокового API - PullRequest
0 голосов
/ 21 января 2019

Привет всем работающим с потоками, возник такой вопрос. У меня есть лист, который я хочу отсортировать по частоте появления в нем символов:

List<String> frequency = new ArrayList<>();
        Collections.addAll(frequency, "gg", "ss", "gg", "boy", "girls", "girls", "gg", "boy", "aa", "aa");

Я написал этот метод:

return words.stream().limit(limit).map(String::toLowerCase)
.collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
                    .entrySet().stream()
                    .map(entry -> new Pair<>(entry.getKey(), entry.getValue()))
                    .collect(Collectors.toList());

Но ответ уже отображается неверно, строка a полностью потеряна, строка gg - это один элемент, а boys - один элемент

ss=1
gg=2
girls=2
boy=1

И я не знаю, как отсортировать их по частоте появления. Результат должен быть таким:

gg=3
aa=2
boy=2
girls=2
ss=1

Как это можно улучшить?

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Вы можете сделать это так,

Map<String, Long> wordCount = frequency.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet().stream()
    .sorted(Map.Entry.<String, Long>comparingByValue(Comparator.reverseOrder())
        .thenComparing(Map.Entry.comparingByKey()))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, 
        (e1, e2) -> e2, LinkedHashMap::new));

Выход: {gg=3, aa=2, boy=2, girls=2, ss=1}

Обратите внимание, что функция mergeFunction здесь НЕ используется, так как нет конфликтов ключей.

0 голосов
/ 21 января 2019

Удалить .limit(limit), так как он заставляет конвейер Stream обрабатывать только первые limit элементы (в зависимости от вашего вывода limit было 6).

return 
   frequency.stream()
            .map(String::toLowerCase)
            .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
            .entrySet().stream()
            .map(entry -> new SimpleEntry<>(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());

Выход:

[aa=2, ss=1, gg=3, girls=2, boy=2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...