tmn*_*tmn 75 java lambda java-8 java-stream
我的同事和我有一个错误是由于我们假设空流调用allMatch()
将返回false
.
if (myItems.allMatch(i -> i.isValid()) {
//do something
}
Run Code Online (Sandbox Code Playgroud)
当然,假设而不是阅读文档是我们的错.但我不明白为什么allMatch()
空流的默认行为返回true
.这是什么原因?就像anyMatch()
(相反地返回false)一样,这个操作以一种离开monad并且可能在if
声明中使用的命令性方式使用.考虑到这些事实,是否有任何理由为什么在大多数用途中需要allMatch()
默认为true
空流?
use*_*ica 99
这被称为空洞真相.空集合的所有成员都满足您的条件; 毕竟,你能指出一个没有的吗?同样,anyMatch
返回false,因为您无法找到与该条件匹配的集合元素.这让很多人感到困惑,但事实证明这是为空集定义"any"和"all"的最有用和最一致的方法.
当我打电话list.allMatch
(或其他语言的模拟)时,我想检测是否有任何项目list
与谓词不匹配.如果没有项目,则没有项目可能无法匹配.我的以下逻辑将选择项目并期望它们与谓词匹配.对于一个空列表,我将不会选择任何项目,逻辑仍然是合理的.
如果allMatch
返回false
空列表怎么办?
我的直截了当的逻辑会失败:
if (!myList.allMatch(predicate)) {
throw new InvalidDataException("Some of the items failed to match!");
}
for (Item item : myList) { ... }
Run Code Online (Sandbox Code Playgroud)
我需要记得用支票替换支票!myList.empty() && !myList.allMatch()
.
简而言之,allMatch
返回true
空列表不仅在逻辑上是合理的,而且还在于快乐的执行路径,需要更少的检查.
这是考虑这个的另一种方式:
allMatch()
是&&
什么sum()
是+
请考虑以下逻辑语句:
IntStream.of(1, 2).sum() + 3 == IntStream.of(1, 2, 3).sum()
IntStream.of(1).sum() + 2 == IntStream.of(1, 2).sum()
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为sum()
它只是一个概括+
.但是,当你删除一个元素时会发生什么?
IntStream.of().sum() + 1 == IntStream.of(1).sum()
Run Code Online (Sandbox Code Playgroud)
我们可以看到IntStream.of().sum()
以特定方式定义数字或空数字序列的总和是有意义的.这给了我们求和的"身份元素",或者当添加到某个东西时没有效果的值(0
).
我们可以将相同的逻辑应用于Boolean
代数.
Stream.of(true, true).allMatch(it -> it) == Stream.of(true).allMatch(it -> it) && true
Run Code Online (Sandbox Code Playgroud)
更一般地说:
stream.concat(Stream.of(thing)).allMatch(it -> it) == stream.allMatch(it -> it) && thing
Run Code Online (Sandbox Code Playgroud)
如果stream = Stream.of()
那么这条规则仍然需要适用.我们可以使用&&的"标识元素"来解决这个问题.true && thing == thing
所以Stream.of().allMatch(it -> it) == true
.