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

我的同事和我有一个错误,这是由于我们的假设,一个空的流调用allMatch()将返回false。为什么Stream.allMatch()对于空流返回true?

if (myItems.allMatch(i -> i.isValid()) { 

//do something

}

当然,假设和不读文档是我们的错。但是我不明白的是为什么空流的默认allMatch()行为返回true。这是什么原因?像anyMatch()(其相反地返回错误)一样,该操作以离开单子并且可能在if声明中使用的命令方式使用。考虑到这些事实,是否有任何理由将allMatch()默认为true在空的流上对大多数用途来说是可取的?

回答:

这就是所谓的vacuous truth。所有空集合的成员都能满足你的条件;毕竟,你能指出一个不是吗?同样,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) { ... }

我需要记住与!myList.empty() && !myList.allMatch()更换检查。

简而言之,allMatch返回true对于一个空列表来说不仅逻辑上合理,它还处于快乐的执行路径上,需要更少的检查。

回答:

它看起来像它的基础是数学归纳。对于计算机科学来说,这可能是一个递归算法的基本情况。

如果流为空,则量化被认为是真实满足并且总是为真。 Oracle Docs: Stream operations and pipelines

这里的关键是它是“真空满意”,其本质上有点误导。维基百科有一个体面的讨论。

在纯数学中,真实的真实陈述本身通常并不感兴趣,但它们经常作为数学归纳证明的基本情况出现。Wikipedia: Vacuous Truth

回答:

这里是另一种方式来思考一下这个

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)的值。

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

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

以上是 为什么Stream.allMatch()对于空流返回true? 的全部内容, 来源链接: utcz.com/qa/258590.html

回到顶部