Подтвердить что ты не робот

Count int вхождения с Java8

Есть ли лучший способ подсчета int вхождения с Java8

int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirthday().getMonthValue() - 1]++);
4b9b3361

Ответ 1

Try:

 Map<Integer, Long> counters = persons.stream()
     .collect(Collectors.groupingBy(p -> p.getBirthday().getMonthValue(), 
         Collectors.counting()));

Ответ 2

С Коллекции 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

Ответ 3

Если вы хотите получить целочисленную карту Integer, вы можете сделать следующее.

Map<Integer, Integer> counters = persons.stream()
    .collect(Collectors.groupingBy(
        p -> p.getBirthday().getMonthValue(),
        Collectors.reducing(0, e -> 1, Integer::sum)));

Ответ 4

Уже ответил. Небольшое предложение с моей стороны, чтобы исключить исключение 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()));

Ответ 5

Там может быть несколько вариантов.

Вы можете использовать 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());

Ответ 6

int size = persons.stream().count()