简体   繁体   English

如何从int流中获取int类型的平均值?

[英]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. 因此,您必须明确地进行从doubleint的转换-同意您将失去一些准确性。

You might be interested in using methods like Math::ceil , Math::floor or Math::round to round up your average. 您可能对使用Math::ceilMath::floorMath::round等方法感兴趣, Math::ceil平均值。 Those methods return double ( Math::round returns long ) too so you will have to apply the cast explicitly too. 这些方法也返回doubleMath::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM