【发布时间】:2014-05-29 03:36:04
【问题描述】:
有没有更好的方法来用 Java8 计算 int 的出现次数
int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirthday().getMonthValue() - 1]++);
【问题讨论】:
有没有更好的方法来用 Java8 计算 int 的出现次数
int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirthday().getMonthValue() - 1]++);
【问题讨论】:
试试:
Map<Integer, Long> counters = persons.stream()
.collect(Collectors.groupingBy(p -> p.getBirthday().getMonthValue(),
Collectors.counting()));
【讨论】:
i -> counters.get(i)
这可能需要一些变化。
您可以使用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());
【讨论】:
通过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));
如果您使用匿名内部类而不是 lambda,此代码也适用于 Java 5 – 7。
注意:我是 Eclipse Collections 的提交者
【讨论】:
如果您想获得 Integer 到 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()));
【讨论】:
int size = persons.stream().count()
【讨论】:
count() 返回 long 你需要转换为 int,所以这不会编译。应该是int size = (int) persons.stream().count()