我有一小段代码,用于计算给定数组中的正值、负值和零值的数量。使用Java 7,通过迭代数组并计算正值、负值和零值的数量,我可以轻松地做到这一点。但对于Java 8流,在map函数中写入条件是否正确?目前,此代码只迭代一次,并跳过数组的其余值。
static void calculatePositiveNegativeAndZero(int[] arr) {
AtomicInteger positive = new AtomicInteger(0);
AtomicInteger zero = new AtomicInteger(0);
AtomicInteger negative = new AtomicInteger(0);
int len = arr.length;
Arrays.stream(arr)
.parallel()
.map(i -> i > 0 ? positive.getAndIncrement() : (i == 0 ? zero.getAndIncrement() : negative.getAndIncrement()));
System.out.println(positive.doubleValue()/len);
System.out.println(negative.doubleValue()/len);
System.out.println(zero.doubleValue()/len);
}
流管道中没有终端操作,因此根本不应该执行它。您可以使用forEach而不是map:
Arrays.stream(arr)
.parallel()
.forEach(i -> {
int k = i > 0 ? positive.getAndIncrement() : (i == 0 ? zero.getAndIncrement() : negative.getAndIncrement());
});
您可以用一种不同的方式来做同样的事情,而无需使用原子XXX:
Map<Integer, Long> map = Arrays.stream(arr)
.boxed()
.collect(Collectors.groupingBy(
Integer::signum,
Collectors.counting()));
System.out.println("positive = " + map.get(1) + " negative = " + map.get(-1) + " zero = " + map.get(0));
您还可以通过创建包装器类来处理此问题。您不需要使用AtomicInteger。使用Java 10,我按照以下方式解决了这个问题。
var wrapper = new Object(){ int positive = 0, negative = 0, zero = 0; };
Arrays.stream(arr)
.parallel()
.forEach(i -> { int tmp = i > 0 ? wrapper.positive++ : (i == 0 ? wrapper.zero++ : wrapper.negative++);});