Хорошо, во-первых, ваша строка wordFrequency
может использовать Collectors#groupingBy
и Collectors#counting
вместо написания вашего собственного аккумулятора:
List<String> incoming = Arrays.asList("monkey", "dog", "MONKEY", "DOG", "giraffe", "giraffe", "giraffe", "Monkey");
wordFrequency = incoming.stream()
.filter(word -> !word.trim().isEmpty()) // filter first, so we don't lowercase empty strings
.map(String::toLowerCase)
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
Теперь, когда мы получили это с пути... Ваша строка TODO говорит use streams to determine maxCnt
.Вы можете сделать это легко, используя max
с naturalOrder
:
int maxCnt = wordFrequency.values()
.stream()
.max(Comparator.naturalOrder())
.orElse(0L)
.intValue();
Однако, ваши комментарии заставляют меня думать, что на самом деле вам нужен однострочный print наиболее часто встречающиеся слова (все) , то есть слова, которые имеют maxCnt
в качестве значения в wordFrequency
.Итак, нам нужно «перевернуть» карту, сгруппировав слова по количеству, а затем выбрать запись с наибольшим количеством:
wordFrequency.entrySet().stream() // {monkey=3, dog=2, giraffe=3}
.collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList()))).entrySet().stream() // reverse map: {3=[monkey, giraffe], 2=[dog]}
.max(Comparator.comparingLong(Map.Entry::getKey)) // maxCnt and all words with it: 3=[monkey, giraffe]
.ifPresent(e -> {
System.out.println("Words that appear " + e.getKey() + " times: " + e.getValue());
});
. Это решение печатает все слова с maxCnt
, вместо одного:
Words that appear 3 times: [monkey, giraffe]
.
Конечно, вы можете объединить операторы, чтобы получить один большой универсальный оператор, например:
incoming.stream() // [monkey, dog, MONKEY, DOG, giraffe, giraffe, giraffe, Monkey]
.filter(word -> !word.trim().isEmpty()) // filter first, so we don't lowercase empty strings
.map(String::toLowerCase)
.collect(groupingBy(s -> s, counting())).entrySet().stream() // {monkey=3, dog=2, giraffe=3}
.collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList()))).entrySet().stream() // reverse map: {3=[monkey, giraffe], 2=[dog]}
.max(Comparator.comparingLong(Map.Entry::getKey)) // maxCnt and all words with it: 3=[monkey, giraffe]
.ifPresent(e -> {
System.out.println("Words that appear " + e.getKey() + " times: " + e.getValue());
});
Но теперь мы расширили значение «одного утверждения»:)