使用Java8计算int出现次数

时间:2014-05-29 03:36:04

标签: java java-8

是否有更好的方法可以使用Java8计算int出现次数

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

6 个答案:

答案 0 :(得分:67)

尝试:

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

答案 1 :(得分:3)

使用Eclipse Collections(以前称为GS Collections),您可以使用名为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));

如果您使用匿名内部类而不是lambdas,此代码也适用于Java 5 - 7.

注意:我是Eclipse Collections的提交者

答案 2 :(得分:0)

如果要获取Integer到Integer的地图,可以执行以下操作。

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

答案 3 :(得分:0)

已经回答。我的小建议,以消除 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()));

答案 4 :(得分:0)

可能会有一些变化。

您可以使用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());

答案 5 :(得分:-4)

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