[英]How to get an average of type int from a stream of int?
I'm writing a program in which I have to get the average delay for trains, but I'm having trouble as the stream must return an int (which means it will approximate the value). 我正在编写一个程序,必须在该程序中获得火车的平均延迟,但是由于流必须返回一个int(这意味着它将接近该值),所以我遇到了麻烦。 I'd prefer not to use a downcast.
我宁愿不要使用垂头丧气。 The following is a code example
以下是代码示例
public int getAvgDelay(){
return trainStop.stream()
.flatMapToInt(a->a.getDelays().stream())
.average().orElse(-1);
}
getDelays() returns a List of Integers with the delays for that train in a single station, I convert it to a stream, then the average will return a double, but I want to find a way to get an Int out of it. getDelays()返回一个整数列表,其中包含该列车在单个站点中的延迟,我将其转换为流,然后平均值将返回双精度值,但是我想找到一种方法来获取整数。
Overall I'm having trouble with most streams where I have to return a single value after using some summarizing collectors, if you could give me a general rule on how to do it I would really appreciate it! 总的来说,我在大多数流中遇到了麻烦,在使用一些汇总收集器之后,我不得不返回单个值,如果您能给我关于如何做的一般规则,我将不胜感激!
The result of average
method is double
(actually it is an OptionalDouble
but that is not the point) . average
方法的结果是double
(实际上是OptionalDouble
但这不是重点)。 If you want to return an integer
, from your method, you have to cast the result to int
explicitly. 如果要从方法返回
integer
,则必须将结果显式转换为int
。 That happens because double is saved on 64 bits wheras integer on 32 bits. 发生这种情况是因为double存储在64位,而整数存储在32位。 So you have to do the casting from
double
to int
explicitly - by that you agree that you will lose some accuracy. 因此,您必须明确地进行从
double
到int
的转换-同意您将失去一些准确性。
You might be interested in using methods like Math::ceil
, Math::floor
or Math::round
to round up your average. 您可能对使用
Math::ceil
, Math::floor
或Math::round
等方法感兴趣, Math::ceil
平均值。 Those methods return double
( Math::round
returns long
) too so you will have to apply the cast explicitly too. 这些方法也返回
double
( Math::round
返回long
),因此您也必须显式应用强制转换。 However those methods will round up to the nearest integer - but still it will be of double
type. 但是这些方法将四舍五入到最接近的整数-但仍然是
double
类型。
This is one method using Math.round()
to round the average value and cast it to an int
: 这是使用
Math.round()
舍入平均值并将其转换为int
:
public int getAvgDelay() {
return trainStop.stream()
.flatMapToInt(a -> a.getDelays().stream())
.average().stream()
.mapToLong(Math::round).mapToInt(i -> (int) i)
.findFirst().orElse(-1);
}
But you should consider to return an Optional instead of a magic number ( -1
). 但是您应该考虑返回Optional而不是幻数(
-1
)。 If you do so you also can return the OptionalDouble
or if you want a whole number an OptionalLong
directly to prevent casting to an int
. 如果这样做,还可以返回
OptionalDouble
或者如果您想要一个整数直接返回OptionalLong
,以防止强制转换为int
。
You then can call your method like this: 然后,您可以像下面这样调用您的方法:
int avg = getAvgDelay().orElse(-1);
Or use .orElseThrow()
if you need an error state. 或者,如果需要错误状态,请使用
.orElseThrow()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.