Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Stream.allMatch()对于空流返回true?_Java_Lambda_Java 8_Java Stream - Fatal编程技术网

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

Java 为什么Stream.allMatch()对于空流返回true?,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我的同事和我有一个bug,这是因为我们假设调用allMatch()的空流将返回false if (myItems.allMatch(i -> i.isValid()) { //do something } 当然,假设而不阅读文档是我们的过错。但我不明白的是,为什么空流的默认allMatch()行为返回true。原因是什么?与anyMatch()(反过来返回false)类似,此操作以命令式方式使用,脱离monad,可能用于if语句。考虑到这些事实,有没有任何理由让空流上的allM

我的同事和我有一个bug,这是因为我们假设调用
allMatch()
的空流将返回
false

if (myItems.allMatch(i -> i.isValid()) { 
    //do something
}
当然,假设而不阅读文档是我们的过错。但我不明白的是,为什么空流的默认
allMatch()
行为返回
true
。原因是什么?与
anyMatch()
(反过来返回false)类似,此操作以命令式方式使用,脱离monad,可能用于
if
语句。考虑到这些事实,有没有任何理由让空流上的
allMatch()
默认值为
true
对于大多数使用是可取的

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


类似地,
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
不仅在逻辑上合理,而且在执行过程中也很顺利,需要更少的检查。

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

如果流为空,则称量化为真空满足,且始终为真

这里的关键是,它是“空洞的满足”,这在本质上有点误导。维基百科对此进行了相当不错的讨论

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


下面是另一种思考方法:

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()。我们可以使用&&的“identity元素”来解决这个问题
true&&thing==thing
,所以
Stream.of().allMatch(it->it)==true

虽然这个问题已经被正确地回答了多次,但我想引入一种更数学的方法

我想把这条河看成一个集合(从数学意义上说)。然后

相当于while

对应于

第二部分为false是很明显的,因为空集中没有元素。第一个有点棘手。你可以从定义上承认它是正确的,也可以从其他答案中寻找它应该是正确的原因


举例说明这种差异的是“所有生活在火星上的人都有三条腿”(真)和“有一个人生活在火星上有三条腿”(假)

在某些情况下,解决办法并不漂亮

示例:验证是否发送了所有请求(但某些类型的请求列表可以为空)

公共布尔值isAllRequestsSent(字符串类型){
//空请求列表
var count=requestsList.stream().filter(Request::type).count();

if(count)这有点奇怪。我们希望如果
allMatch
返回true,那么
anyMatch
也应该返回true。此外,对于空的情况,
allMatch(…)==noneMatch(…)
这也很奇怪。维基百科说这是一个惯例:只是简单地撇开语法:不用将谓词写成
i->i.isValid()
,你可以编写
Foo::isValid
(当然,
Foo
是你正在流化的任何类)“这个操作是以命令式的方式使用的,脱离了monad”-我怀疑这会影响任何决策。天哪,我讨厌布尔逻辑。我想我明白你的意思了。没有负数是正的,但没有正数不是负的。@ThomasN。同样,一组空数的乘积值是
1
,而一组空数的和是
0
。它们是乘法/加法的中性元素。在布尔数的情况下,你有
真和x=x
假或x=x
,因此如果你将
推广到序列(这就是
所有
任何
都是)对于空的情况,您将得到
True
False
,即它们各自是中性元素。@ThomasN.
anyMatch
测试是否存在阳性,
allMatch
测试是否存在阴性。注意
emptyStream.allMatch(x-> p(x))
emtpyStream.anyMatch(x -> p(x))
public boolean isAllRequestsSent(String type){

        //empty request List
        var count = requestsList.stream().filter(Request::type).count();
        
        if(count <= 0) {
            return false;
        }
    
        return requestsList.stream().filter(Request::type).allMatch(RequestData::isSent);
        }