我正试图更加了解流,因此我正在做一些基本练习。在此,我想计算奇数的平均值。我为此编写了算法,但返回的结果不正确(8.0)。我尝试调试它,但实际上找不到它。
List<Integer> numbers = Arrays.asList(1, 3, -2, -4, -7, -3, -8, 12, 19, 6, 9, 10, 14);
OptionalDouble result = numbers.stream()
.filter(i -> i % 2 == 1)
.mapToDouble(i -> i).average();
if (result.isPresent()) {
System.out.println(result);
} else {
System.out.println("Error");
}
我的代码现在在做什么?我应该如何解决它应做的事?
答案 0 :(得分:11)
(i -> i % 2 == 1)
这仅适用于正奇数,因为在Java中,%
运算符的第一个操作数为负数时将返回负数(或零)。
如果您只想保留偶数数字,则应为:
(i -> i % 2 == 0)
如果要保留所有奇数(正数和负数),可以使用:
(i -> i % 2 != 0)
答案 1 :(得分:3)
我的代码现在在做什么?
您正在执行modulo operation on negative number。
我应该如何解决它应做的事?
您可以使用Math.abs
来验证列表中的绝对值是否为奇数:
OptionalDouble result = numbers.stream()
.filter(i -> Math.abs(i) % 2 == 1) // verify id the absolute value is odd
.mapToDouble(i->i).average();
答案 2 :(得分:2)
除了@khelwood提到的带负数模的内容之外。
重要的是要知道,filter
中间操作不会删除元素,也不会进行任何流操作,相反,filter
返回一个新的流,其中所有元素满足提供的谓词,即i -> i % 2 == 1
。
i -> i % 2 == 1
表示“如果元素是奇数,则仅将其表示为i
”。
如果您愿意的话,甚至应该执行i -> i % 2 == 0
,读为“仅保留表示为i
的元素,因为它是偶数”。
另一方面,如果您在JDK9上运行,则可以使用ifPresentOrElse
来简单地进行isPresent()
检查。
numbers.stream()
.filter(i -> i % 2 == 0)
.mapToDouble(i -> i)
.average()
.ifPresentOrElse(System.out::println,
() -> System.out.println("Error"));