Count int occurrences with Java8

一世执手 提交于 2019-12-27 12:24:08

问题


Is there a better way to count int occurrences with Java8

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

回答1:


Try:

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



回答2:


With Eclipse Collections (formerly GS Collections), you can make use of a data structure called Bag that can hold the number of occurrences of each element.

Using IntBag, the following will work:

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));

If you want to make use of an array to keep track of the count, you can combine with the Arrays.setAll() approach Brian pointed out in another answer.

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));

This code will also work with Java 5 – 7 if you use anonymous inner classes instead of lambdas.

Note: I am a committer for Eclipse Collections




回答3:


If you would like to get Integer to Integer map, you can do the following.

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



回答4:


Already answered. Small Suggestion from my side inorder to eliminate null pointer exception ie From the stream null will throw 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:


There's a few variations this could take.

You can use Collectors.summingInt() to use Integer instead of the Long in the count.

If you wanted to skip the primitive int array, you could store the counts directly to a List in one iteration.

Count the birth months as Integers

Map<Integer, Integer> monthsToCounts = 
        people.stream().collect(
                Collectors.groupingBy(p -> p.getBirthday().getMonthValue(), 
                Collectors.summingInt(a -> 1)));

Store the birth months in a 0-based array

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);

Skip the array and directly store the values to a list

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()


来源:https://stackoverflow.com/questions/23925315/count-int-occurrences-with-java8

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!