为什么没有 OptionalDouble orElseNull() 或更好的解决方案

Why no OptionalDouble orElseNull() or a better solution

我有一个计算平均成本的流代码看起来像这样

private Double calculateAverageCost(List<Item> items) {
    return items.stream()
                .mapToDouble(item -> item.cost)
                .filter(cost -> cost > 0) // Ignore zero cost items
                .average()
                . // Something here to convert an OptionalDouble to value or null
}

我需要方法 return 值或 null 如果没有值(例如,当所有成本为零时)。我的问题是 OptionalDouble 上没有 orElseNull 方法来进行转换。我可以在另一个步骤中完成,例如

private Double calculateAverageCost(List<Item> items) {
    final OptionalDouble average = items.stream()
                .mapToDouble(item -> item.cost)
                .filter(cost -> cost > 0) // Ignore zero cost items
                .average();
    return average.isPresent() ? average.getAsDouble() : null;
}

我意识到这是一个“原始”流,我的方法是 return 装箱 Double 但看起来这可能会有帮助,类似于 (Optional.empty().orElseGet(null))。

我缺少原因或更好的解决方案吗?

OptionalDouble 包含一个 primitive double。如果你想要一个可选的包装双精度,你可以使用 Optional<Double>。基元不能为空,因此 orElseNull 没有意义。

至于两者之间如何转换,这里已经有答案:Convert OptionalDouble to Optional <java.lang.Double>. TL;DR there is no nice, native way to do it yet. Wait for valhalla

如果您 returning null 只是为了表明所有成本都是 0(或列表为空),那么您可以 return Double.NaN 代替。这将使您的 return 类型成为原始类型 double.

private double calculateAverageCost(List<Item> items) {
    return items.stream()
                .mapToDouble(item -> item.cost)
                .filter(cost -> cost > 0) // Ignore zero cost items
                .average()
                .orElse(Double.NaN);
}
double avg = calculateAverageCost(items);
if(Double.isNaN(avg)) {
    System.out.println("All costs are zero");
}

否则,您可以使用 orElse(0d)。由于您过滤 仅正成本 ,因此仅当所有成本均为 0(或列表为空)时,平均值才为 0。因此,如果结果为 0,则肯定意味着不存在正成本。