Java 8 中的 anyMatch()

10 Sept 2024 | 5 分钟阅读

Java 8 中的 anyMatch() 是 Stream 接口中定义的一个方法。它执行**短路终端操作**。在本节中,我们将通过一个示例讨论 **Java 8 Stream 中的 anyMatch() 方法**。在深入主题之前,我们先详细了解一下中间操作和终端操作。

在 Java 8 Stream 中,Stream 操作分为**中间操作**(如 Stream.filter、Stream.map)和**终端操作**(如 Stream.forEach、Stream.reduce)两类。为了获得期望的结果,我们需要将这些操作组合起来形成 Stream 流水线。

中间操作

中间操作本质上是惰性的(意味着,不执行实际操作,而是返回一个新的流)。这意味着,它保留了初始流的元素,并始终返回一个由初始流构成的新流。请注意,流的执行要到流流水线的终端操作被执行时才会开始。

中间操作进一步分为**无状态**操作(如 filter 和 map)和**有状态**操作(如 distinct 和 sorted)。

无状态操作

无状态操作在处理新元素时,不会保留来自先前元素的任何状态。每个元素都可以独立于其他元素的操作进行处理。

有状态操作

有状态操作在处理新元素时,会保留来自先前元素的任何状态。有状态操作的特性是,它在产生结果之前会处理所有输入。

假设我们正在对流执行排序操作,并希望在不查看流的所有元素的情况下从该流产生结果,这是不可能的。因此,除非看到了流的所有元素,否则无法产生结果。因此,我们需要在产生结果之前处理所有输入。

终端操作

终端操作遍历流以产生结果或产生副作用。一旦执行了终端操作,流流水线就被认为是已消耗。消耗后,它将无法再使用。如果需要遍历相同的数据源(流),则需要返回流以获取新流。

几乎所有的终端操作都是急切的。这意味着,它们在返回之前会遍历流并处理流水线。请注意,对于 iterator() 和 spliterator() 这两个终端操作是不允许的。

除了上述操作之外,还有一种称为**短路**操作。中间操作和终端操作都可以是短路的。

如果一个流具有无限输入,那么它是一个短路中间操作。它可以产生一个有限的流作为结果。

如果一个流具有无限输入,那么它是一个短路终端操作。它可以在有限的时间内终止。

我们观察到,在流水线中使用短路操作是必要但不充分的。有一个条件需要处理无限流,那就是**在有限时间内正常终止**。

Java 8 Stream.anyMatch()

它返回此流中的任何元素是否与提供的谓词匹配。如果无需确定结果,则可能不会对所有元素评估该谓词。

语法

参数:它接受一个**非干扰性**且**无状态**的谓词,该谓词将应用于输入流的元素。

返回值:如果任何元素与指定的谓词匹配,则返回 **true**,否则返回 false。如果流为空,则返回 false。在流为空的情况下,不会评估谓词。

Java anyMatch() 示例

AnyMatchExample1.java

输出

true

以下示例显示空流始终返回 false。

AnyMatchExample2.java

输出

false

让我们看另一个 Java 程序,其中我们解析了多个谓词。

要满足多个条件,请创建具有两个或多个简单谓词的组合谓词。在给定的示例中,我们有一个 Employee 列表。我们想检查是否有一个员工的年龄为 28 岁,并且名字以字母 R 开头。以下 Java 程序对此进行了说明。

AnyMatchExample.java

输出

true
true
false

Stream 接口提供了另一个匹配指定谓词的方法,即 **allMatch()**。allMatch() 和 anyMatch() 之间的区别在于,anyMatch() 在流中的任何元素匹配指定谓词时返回 **true**。当使用 allMatch() 时,所有元素都必须匹配给定的谓词。

因此,anyMatch() 方法可以在我们想检查流中至少有一个元素匹配的特定情况下使用。List 类的 contains() 方法也执行相同的操作。因此,我们也可以在 anyMatch() 方法的替代方案中使用 contains() 方法。

因此,List.contains() 和 Stream.anyMatch() 方法之间没有区别。