【问题标题】:How to get an average of type int from a stream of int?如何从 int 流中获取 int 类型的平均值?
【发布时间】:2019-06-30 17:16:36
【问题描述】:

我正在编写一个程序,我必须在其中获取火车的平均延迟,但我遇到了麻烦,因为流必须返回一个 int(这意味着它将近似值)。我宁愿不使用沮丧。 以下是代码示例

public int getAvgDelay(){
  return trainStop.stream()
                  .flatMapToInt(a->a.getDelays().stream())
                  .average().orElse(-1);
}

getDelays() 返回一个整数列表,其中包含该列车在单个车站的延误,我将其转换为流,然后平均值将返回双倍,但我想找到一种方法来获取 Int它。

总的来说,我在使用一些汇总收集器后必须返回单个值的大多数流中遇到问题,如果您能给我一个关于如何做到这一点的一般规则,我将不胜感激!

【问题讨论】:

  • 为什么不能将结果转换为 int?当然你会失去准确性,但是当你有 double 并且你想要整数时会发生这种情况。
  • 没有办法“从”average 函数中“获取 int”。您只需通过强制转换/截断或使用Math.round 将其转换为int。 (请注意,round 返回 long,因此您仍然必须将其转换为 int,这应该没问题,因为输入都是 ints。)
  • 我的意思是我不想创建一个 double 然后将其转换为一个 int,如果可能的话,我宁愿用流一次做所有事情
  • @Paglie98 1) 这是不可能的; 2) 将 double 转换为 int 是微不足道的,无论是在语法上还是在运行时成本方面。

标签: java java-stream


【解决方案1】:

average 方法的结果是double(实际上是OptionalDouble,但这不是重点)。如果你想从你的方法中返回一个integer,你必须将结果显式地转换为int。发生这种情况是因为 double 保存在 64 位上,而整数保存在 32 位上。所以你必须明确地从double 转换到int - 你同意你会失去一些准确性。

您可能有兴趣使用Math::ceilMath::floorMath::round 等方法对您的平均值进行四舍五入。这些方法也返回doubleMath::round 返回long),因此您也必须显式应用强制转换。然而,这些方法将四舍五入到最接近的整数 - 但它仍然是 double 类型。

【讨论】:

    【解决方案2】:

    这是一种使用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);
    }
    

    但您应该考虑返回 Optional 而不是幻数 (-1)。如果这样做,您还可以返回 OptionalDouble,或者如果您想要一个整数,则直接返回 OptionalLong 以防止转换为 int

    然后你可以这样调用你的方法:

    int avg = getAvgDelay().orElse(-1);
    

    如果您需要错误状态,请使用.orElseThrow()

    【讨论】:

      猜你喜欢
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多