是否有使用Java 8功能简化以下代码块的建议?
int[] ans = new int[2];
list.forEach(i -> {
if (i > 0) {
ans[0] += 1;
} else if (i < 0) {
ans[1] += 1;
}
});
P.S。不确定是否应该发布此here
答案 0 :(得分:4)
如果您不想计数零,则代码将尽可能简单。如果您想将零视为正数,则可以将其缩短为此。
int[] ans = new int[2];
for (int i : list) ans[i < 0 ? 1 : 0] += 1;
答案 1 :(得分:2)
ans[0] = (int)list.stream().filter(x -> x < 0).count();
ans[1] = (int)list.stream().filter(x -> x > 0).count();
但是我几乎不认为这是一个简化,您的解决方案已经尽可能简单。
如果您确实想计数零,则可以简化为:
list.forEach(x -> ++ans[x >>> 31])
答案 2 :(得分:1)
我建议
int[] ans = new int[2];
list.forEach(i -> ans[i >>> 31] += i==0 ? 0 : 1);
其中i >>> 31
丢弃除符号位(即与i<0 ? 1 : 0
相同)之外的所有字符,而第二个条件句柄则为零。
我不主张,它确实比原始版本好。
答案 3 :(得分:1)
要区分两种情况,例如i > 0
和i < 0
,我们可以使用Stream.partition
:
Map<Boolean, List<Integer>> partitioned = list.stream()
.filter(i -> i != 0)
.collect(Collectors.partitioningBy(i -> i > 0));
ans[0] = partitioned.get(true).size();
ans[1] = partitioned.get(false).size();
是否已简化?至少它仍然可读且易于理解。
编辑
或如@ saka1029所示:
Map<Boolean, Long> partitioned = list.stream()
.filter(i -> i != 0)
.collect(Collectors.partitioningBy(i -> i > 0, Collectors.counting()));
ans[0] = partitioned.get(true);
ans[1] = partitioned.get(false);
编辑
还有另一个Stream
解决方案,它返回所需的数组。但我认为这并不简单。因此,它将进行比较。
int[] ans = list.stream().filter(i -> i != 0).collect(
() -> new int[2],
(arr, i) -> arr[i > 0 ? 0 : 1]++,
(l, r) -> { l[0] += r[0]; l[1] += r[1]; });
答案 4 :(得分:0)
这也是一种计算零的方法:
int[] ans = new int[3];
list.forEach(i -> ans[Integer.signum(i) + 1] += 1);
ans
数组现在具有3个值:索引0表示负数,索引1表示零数,索引2表示正数。
即对于以下输入:[1, 2, 3, 0, -4, -5]
,输出将是:[2, 1, 3]
。
一种更实用的方式,不包括零:
Map<Integer, Long> bySignum = list.stream()
.filter(i -> i != 0)
.collect(Collectors.groupingBy(Integer::signum, Collectors.counting()));
哪个产生以下输出:{-1=2, 1=3}
。