Java 8 получить элементы с одинаковым максимальным количеством вхождений - PullRequest
0 голосов
/ 02 июня 2018

У меня есть поток элементов, и я хочу преобразовать его в другой поток, который будет состоять только из элементов, которые больше всего отображались в предыдущем потоке, при условии, что у меня может быть несколько элементов с одинаковым числом вхождений.

Например:

Входной поток: ['A', 'B', 'A', 'B', 'C', 'C', 'A', 'B']

Выходной поток: ['A', B '], поскольку у них обоих максимальное количество вхождений в предыдущем потоке равно 3.

Пока что я написал следующий код:

stream.collect(toMap(w -> w, w -> 1, Integer::sum))
                .entrySet()
                .stream()
                .max(comparing(Map.Entry::getValue))
                .map(Map.Entry::getKey);

Но это позволяет мне получить только один из элементов с максимальным числом вхождений, и для приведенного выше случая это даст либо «A», либо «B».

Есть ли какой-нибудь элегантный способо том, как этого можно добиться с помощью лямбды?

Спасибо, ура

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Это должно помочь вам.

final List<Character> maxOccuringChars = chars.stream()
        .collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity(), Collectors.counting()),
                map -> map.entrySet().stream()
                        .filter(entry -> entry.getValue().longValue() == map.entrySet().stream()
                                .max(Map.Entry.comparingByValue()).get().getValue().longValue())
                        .map(Map.Entry::getKey).collect(Collectors.toList())));

Вывод:

[A, B]

Обновление

Я изменил ответ согласно комментарию ниже.

0 голосов
/ 02 июня 2018

Нет простого способа сделать это за один раз, но вы можете отсортировать карту, чтобы найти максимальное значение, или просто использовать IntStream::max, чтобы найти его, а затем отфильтровать карту, чтобы найти все записи, соответствующие этому значению:

var map = Stream.of('A', 'B', 'A', 'B', 'C', 'C', 'A', 'B')
    .collect(toMap(w -> w, w -> 1, Integer::sum));

int max = map.values().stream()
    .mapToInt(n -> n)
    .max().orElse(0);

map.entrySet().stream()
    .filter(e -> max == e.getValue())
    .forEach(System.out::println);

Выход:

A=3
B=3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...