当前位置: 首页 > 知识库问答 >
问题:

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

韦飞尘
2023-03-14

我试图用lambdas计算一些值之间的最小值。这些值可能包含空值,这在我的业务案例中是正常的,因为它们代表间隔限制。例如,如果我有下一个区间(null,10],(10,15),[20,null),我想检查值(null,10,20)之间的最小区间边界,我希望结果是null(作为商业案例规则,null应该被视为无穷大的等价物)。

我尝试用流实现这个,但是我注意到Stream类中的min方法不能用于这样的场景。

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

原因在min方法Javadoc“Throws:NullPointerException-如果最小元素为null”中描述。我尝试了一种变通方法,并使用reduce而不是min,但我遇到了完全相同的问题:

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

我在这里遗漏了什么,还是这是一个API限制,我应该坚持fors和if?

共有1个答案

梁丘权
2023-03-14

不能返回一个null结果,连接到可选,另请参阅,"为什么findFirst()抛出一个NullPointerExctive,如果它找到的第一个元素是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;
}
 类似资料:
  • 问题内容: 我们有一些代码根据其坐标之间的距离对地址列表进行排序。这是通过使用自定义比较器的collections.sort完成的。 但是,列表中有时不包含地址,这会导致NullPointerException。解决这个问题的最初想法是让比较器返回至少0个坐标为零的地址的距离。我担心这可能导致列表中“有效”元素的顺序损坏。 因此是否可以在比较器中为空数据返回“ 0”值,还是有一种更干净的方法来解决

  • 我们知道我们可以将null赋给可为null的类型。例如: 我们知道第二种说法是有效的,因为有人告诉我们它是有效的,我们只是接受它,而不问为什么。但如果查看的源代码,则为: 我们可以将赋给为的原因是由于隐式运算符,它允许您隐式强制转换int为。根据隐式运算符的规则,作为的右手边,必须是结构类型,但显然不是合法的结构值,那么如何做(更不用说本身就是一个结构),为什么不违反隐式运算符规则

  • 问题内容: 我们的代码库中有几个空的抽象类。我觉得很丑。但是除了这个非常愚蠢的原因(丑陋)之外,我是否应该将其重构(例如,插入空接口)? 否则,代码将很健壮并经过良好测试。因此,如果仅出于“审美”原因,我将通过并保留空的抽象类。 你怎么看? 编辑: 1)“空抽象类”的意思是: 2)“空”的原因:休眠。我根本不掌握这个持久性框架。我只知道不能将接口映射到表,并且由于这个技术原因,类比接口更受欢迎。

  • 谁能解释一下为什么下面的代码不起作用: 但这一个有效: 换句话说,与创建普通类实例相比,接口实现何时是可互换的?当我使用compareTo()方法时会出现错误,该方法是Comparable接口的一部分,由所有包装类(如整数)实现。 所以我猜

  • 问题内容: 为什么Hashtable不带钥匙? 另外,为什么HashMap允许键? 使这两个类的键行为如此不同的目的是什么? 问题答案: 从 JavaDoc: 简而言之,由于不是对象,因此无法调用或对其进行调用,因此无法计算哈希值以将其用作键。 较新,并且具有更高级的功能,基本上只是对功能的改进。这样,在创建时,它专门设计为将值作为键来处理,并将它们作为特殊情况来处理。 具体来说,在发出时,像这样

  • > 我看到接口只允许实现方法。那么为什么我们甚至需要这个接口呢?为什么我们不能简单地在我们想要的任何类中定义和声明该方法,而无需实现接口? 我知道这是正确的: