java - 为什么 Java Streams min 方法不接受空值,即使使用的比较器是空友好的?

标签 java lambda java-stream

我正在尝试使用 lambda 计算某些值之间的最小值。这些值可能包含空值,这对我的业务案例来说是正常的,因为它们代表间隔限制。例如,如果我有下一个间隔 (null, 10], (10, 15], [20, null) - 我想检查哪个是值之间的最低间隔边界 (null , 10, 20) 并且我希望 null 成为结果(因为 null 应该被视为等同于 –infinity 作为业务案例规则)。

我尝试用流实现它,但我注意到 Stream 类的 min 方法不能用于这种情况。

private Integer lowestIntervalLimit(Integer... intervalsLowerLimits) {
    return Arrays.stream(intervalsStart)
            .min(nullsFirst(Integer::compareTo))
            .orElse(null);
}

原因在 min 方法 Javadoc“Throws: NullPointerException - if the minimum element is null”中有描述。我尝试了一种解决方法并使用 reduce 而不是 min 但我遇到了完全相同的问题:

private Integer lowestIntervalLimit(Integer... intervalsLowerLimits) {
    return Arrays.stream(intervalsStart)
            .reduce(BinaryOperator.minBy(nullsFirst(Integer::compareTo)))
            .orElse(null);
}

我是不是遗漏了什么或者这是一个 API 限制,我应该坚持 fors 和 ifs?

最佳答案

无法返回 null 结果,连接到 Optional,另请参阅,“Why does findFirst() throw a NullPointerException if the first element it finds is null? ”。

因为您的输入是一个普通数组,所以没有理由担心迭代它两次,例如

private Integer lowestIntervalLimit(Integer... intervalsLowerLimits) {
    return Arrays.stream(intervalsLowerLimits).anyMatch(Objects::isNull)? null:
        Arrays.stream(intervalsLowerLimits).min(Comparator.naturalOrder()).orElse(null);
}

但如果这是一个问题,你可以使用循环

private Integer lowestIntervalLimit(Integer... intervalsLowerLimits) {
    Integer i = null;
    for(Integer j: intervalsLowerLimits)
        if(j == null) return null; else if(i==null || j<i) i = j;
    return i;
}

关于java - 为什么 Java Streams min 方法不接受空值,即使使用的比较器是空友好的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48527514/

相关文章:

java - 使用 Jackson 反序列化 LocalDateTime

c# - 异步 lambda 的执行有什么区别吗?

java - 标准 Kotlin 库中有哪些 Java 8 Stream.collect 等效项?

java - 如何在遍历数组时删除元素

java - 如何根据元素之和对包含整数列表的列表进行排序

JAVA:使用计数器格式化字符串

java - zookeeper 客户端不向 CLI 提供 "jline support is disabled"消息

java - simple-xml null 到 nil

Java 8 : Syntax for Implementing java. util.function.Function 作为 Lambda 表达式

python - 仅使用 lambda 函数删除重复项