Есть ли лучший способ подсчета int вхождения с Java8
int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirthday().getMonthValue() - 1]++);
Есть ли лучший способ подсчета int вхождения с Java8
int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirthday().getMonthValue() - 1]++);
Try:
Map<Integer, Long> counters = persons.stream()
.collect(Collectors.groupingBy(p -> p.getBirthday().getMonthValue(),
Collectors.counting()));
С Коллекции Eclipse (ранее Коллекции GS), вы можете использовать структуру данных с именем Bag
, которая может содержать количество вхождений каждого элемента.
Используя IntBag
, будет работать следующее:
MutableList<Person> personsEC = ListAdapter.adapt(persons);
IntBag intBag = personsEC.collectInt(person -> person.getBirthDay().getMonthValue()).toBag();
intBag.forEachWithOccurrences((month, count) -> System.out.println("Count of month:" + month + " is " + count));
Если вы хотите использовать массив для отслеживания счета, вы можете комбинировать с подходом Arrays.setAll()
Brian, указанным в другом ответе,
int[] monthCounter = new int[12];
MutableList<Person> personsEC = ListAdapter.adapt(persons);
IntBag bag = personsEC.collectInt(person -> person.getBirthDay().getMonthValue()).toBag();
Arrays.setAll(monthCounter, bag::occurrencesOf);
System.out.println(IntLists.immutable.with(monthCounter));
Этот код также будет работать с Java 5-7, если вы используете анонимные внутренние классы вместо lambdas.
Примечание: я являюсь коммиттером для коллекций Eclipse
Если вы хотите получить целочисленную карту Integer, вы можете сделать следующее.
Map<Integer, Integer> counters = persons.stream()
.collect(Collectors.groupingBy(
p -> p.getBirthday().getMonthValue(),
Collectors.reducing(0, e -> 1, Integer::sum)));
Уже ответил. Небольшое предложение с моей стороны, чтобы исключить исключение null- указателя, т.е. Из потока null будет выбрано java.lang.UnsupportedOperationException, java.lang.NullPointerException
Map<Integer, Long> birthdayCount = persons.stream()
.filter(Objects::nonNull) // filter out null object
.filter(p->Objects.nonNull(p.getBirthday())) // filter out null birthdays
.collect(Collectors.groupingBy(p ->
p.getBirthday().getMonthValue(),
Collectors.counting()));
Там может быть несколько вариантов.
Вы можете использовать Collectors.summingInt()
чтобы использовать Integer
вместо Long
в счетчике.
Если вы хотите пропустить массив примитивов int
, вы можете сохранить счет непосредственно в List
за одну итерацию.
Посчитайте месяцы рождения как целые числа
Map<Integer, Integer> monthsToCounts =
people.stream().collect(
Collectors.groupingBy(p -> p.getBirthday().getMonthValue(),
Collectors.summingInt(a -> 1)));
Храните месяцы рождения в массиве на основе 0
int[] monthCounter = new int[12];
people.stream().collect(Collectors.groupingBy(p -> p.getBirthday().getMonthValue(),
Collectors.summingInt(a -> 1)))
.forEach((month, count) -> monthCounter[month-1]=count);
Пропустить массив и напрямую сохранить значения в списке
List<Integer> counts = people.stream().collect(
Collectors.groupingBy(p -> p.getBirthday().getMonthValue(),
Collectors.summingInt(a -> 1)))
.values().stream().collect(Collectors.toList());
int size = persons.stream().count()