Count int occurrences with Java8

后端 未结 6 830
北恋
北恋 2020-11-27 06:12

Is there a better way to count int occurrences with Java8

int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirt         


        
相关标签:
6条回答
  • 2020-11-27 06:33

    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)));
    
    0 讨论(0)
  • 2020-11-27 06:35

    Try:

     Map<Integer, Long> counters = persons.stream()
         .collect(Collectors.groupingBy(p -> p.getBirthday().getMonthValue(), 
             Collectors.counting()));
    
    0 讨论(0)
  • 2020-11-27 06:40

    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()));
    
    0 讨论(0)
  • 2020-11-27 06:43

    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

    0 讨论(0)
  • 2020-11-27 06:47
    int size = persons.stream().count()
    
    0 讨论(0)
  • 2020-11-27 06:51

    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());
    
    0 讨论(0)
提交回复
热议问题