为什么 Stream.allMatch() 对空流返回 true?

新手上路,请多包涵

我和我的同事有一个错误,这是由于我们假设调用 allMatch() 的空流将返回 false

 if (myItems.allMatch(i -> i.isValid()) {
    //do something
}

当然,假设而不阅读文档是我们的错。但我不明白的是为什么空流的默认 allMatch() 行为返回 true 。这样做的原因是什么?与 anyMatch() (相反返回 false)一样,此操作以脱离 monad 的命令方式使用,并且可能用于 if 语句。考虑到这些事实,有什么理由可以让 allMatch() 默认为 true 对于大多数用途来说是理想的空流?

原文由 tmn 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

这被称为 空洞的真理。空集合的所有成员都满足您的条件;毕竟,你能指出一个没有的吗?

同样, anyMatch 返回 false ,因为您无法在集合中找到与条件匹配的元素。这让很多人感到困惑,但事实证明这是为空集定义“任何”和“所有”的最有用和最一致的方式。

原文由 user2357112 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是另一种思考方式:

allMatch()&& 什么 sum()+

考虑以下逻辑语句:

 IntStream.of(1, 2).sum() + 3 == IntStream.of(1, 2, 3).sum()
IntStream.of(1).sum() + 2 == IntStream.of(1, 2).sum()

这是有道理的,因为 sum() 只是 + 的概括。但是,当您再删除一个元素时会发生什么?

 IntStream.of().sum() + 1 == IntStream.of(1).sum()

我们可以看到以特定方式定义 IntStream.of().sum() 或空数字序列的总和是有意义的。这给了我们求和的“身份元素”,或者当添加到某物时没有效果的值( 0 )。

我们可以将相同的逻辑应用于 Boolean 代数。

 Stream.of(true, true).allMatch(it -> it) == Stream.of(true).allMatch(it -> it) && true

更一般地说:

 stream.concat(Stream.of(thing)).allMatch(it -> it) == stream.allMatch(it -> it) && thing

如果 stream = Stream.of() 那么这条规则仍然需要适用。我们可以使用 && 的“身份元素”来解决这个问题。 true && thing == thing ,所以 Stream.of().allMatch(it -> it) == true

原文由 Hans 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题