Вопрос:
У меня есть список массивов с 5 элементами, каждый из которых является Enum. Я хочу создать метод, который возвращает другой список массивов с наиболее распространенными элементами в списке.
Пример 1:
[Activities.WALKING, Activities.WALKING, Activities.WALKING, Activities.JOGGING, Activities.STANDING]
Метод будет возвращен: [Activities.WALKING]
Пример 2:
[Activities.WALKING, Activities.WALKING, Activities.JOGGING, Activities.JOGGING, Activities.STANDING]
Метод будет возвращен: [Activities.WALKING, Activities.JOGGING]
ЧТО ИМЕЛО:
Моя идея состояла в том, чтобы объявить счет для каждого действия, но это означает, что если я хочу добавить другое действие, мне нужно пойти и изменить код, чтобы добавить еще один счет для этого действия.
Другая идея состояла в том, чтобы объявить HashMap<Activities, Integer> и перебрать массив, чтобы вставить каждое действие и его появление в нем. Но тогда как я извлечу действия с наибольшим количеством случаев?
Можете ли вы мне помочь?
Лучший ответ:
Наиболее распространенным способом реализации чего-то подобного является подсчет с помощью Map: определение Map<MyEnum,Integer> которая хранит нули для каждого элемента вашего перечисления. Затем пройдите через свой список и увеличьте счетчик для каждого элемента, который вы найдете в списке. В то же время поддерживайте текущий max счетчик. Наконец, пройдите записи записей счетчика и добавьте в список вывода ключи всех записей, счетчики которых соответствуют значению max.
Ответ №1
В статистике это называется “режимом” (в вашем конкретном случае также используется “многорежимный режим”, поскольку вы хотите, чтобы все значения отображались чаще всего, а не только один). Решение Vanilla Java 8 выглядит так:
Map<Activities, Long> counts = Stream.of(WALKING, WALKING, JOGGING, JOGGING, STANDING) .collect(Collectors.groupingBy(s -> s, Collectors.counting())); long max = Collections.max(counts.values()); List<Activities> result = counts .entrySet() .stream() .filter(e -> e.getValue().longValue() == max) .map(Entry::getKey) .collect(Collectors.toList());
Который дает:
[WALKING, JOGGING]
jOOλ – это библиотека, которая поддерживает modeAll() в потоках. Следующая программа:
System.out.println( Seq.of(WALKING, WALKING, JOGGING, JOGGING, STANDING) .modeAll() .toList() );
Урожайность:
[WALKING, JOGGING]
(отказ от ответственности: я работаю в компании за jOOλ)