📜  Java filter() 方法如何在后台工作?

📅  最后修改于: 2021-10-28 02:45:50             🧑  作者: Mango

filter() 方法在函数式编程中用作中间方法。谓词是一个无干扰的、无状态的谓词,应用于每个元素以确定是否应该包括它。

语法: filter() 方法

filter(Predicate predicate)

参数:谓词

返回类型:由元素组成的流 传递与给定谓词匹配的流。

您有没有想过当我们编写下面的示例时会发生什么,该示例是一个 lambda 表达式,其中元素映射到“ element%2==0那么屏幕背后究竟发生了什么,它实际上是如何工作的?这一切的魔力都基于一种叫做功能接口的东西,因为功能接口只有一个抽象方法。由于默认方法具有实现,因此它们不是抽象的。例如 Predicate Interface、Consumer Interface 都是函数式接口。

List.of(10,5,23,54).stream().filter(element -> element%2==0);

实现:考虑下面的程序,它使用 filter() 方法消除奇数并返回可被 2 整除的数字流,即偶数。

示例 1:

Java
// Java Program to deminstarte Use of filter() Method
  
// Importing all. input output classes
import java.io.*;
// Importing List class from java.util package
import java.util.List;
  
// Main class
class GFG {
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // 1. Creating List of integers later on
        // 2. converting List to a Stream in which
        // 3. logic is to eliminate the odd numbers and
        // finally
        // 4. Printing each element of stream returned by
        // filter() method
        List.of(12, 34, 67, 19, 32, 4)
            .stream()
            .filter(element -> element % 2 == 0)
            .forEach(
                element -> System.out.println(element));
    }
}


Java
// Java Program to Implementation of the Predicate interface
  
// Importing input output classes
import java.io.*;
// Importing classes from java.util package
import java.util.List;
import java.util.function.Predicate;
  
// Class 1
// helper class
// Implementation of Predicate interface
class EvenNumberPredicate implements Predicate {
  
    // Implementing all unimplemented method of the
    // Predicate interface.
    // @Override
    public boolean test(Integer number)
    {
  
        // Returns true for Even and false for Odd
        return number % 2 == 0;
    }
}
  
// Class 2
// Main class
class GFG {
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // 1. Creating List of integers then
        // 2. Converting list to stream further
        // 3. Passing the object of Predicate to the filter
        // mehtod
        List.of(12, 34, 67, 19, 32, 4)
            .stream()
            .filter(new EvenNumberPredicate())
            .forEach(
                element -> System.out.println(element));
    }
}


输出
12
34
32
4

内部工作流程

  • 当 [12, 34, 67, 19, 32, 4] 流传递给 filter 方法时,它使用提供的谓词 (element → element%2==0) 测试每个元素并返回偶数流 [ 12, 34, 32, 4]。
  • 现在,屏幕后面发生了什么?代码片段“ element → element%2 == 0 ”如何发送到过滤器方法。
  • 如果我们查看 filter() 方法的签名如下所示,可以看到它在参数中采用了 Predicate。
public abstract Stream filter(Predicate predicate)
  • 所以当我们查看 Predicate 的文档时,它有如下签名,上面写着@FunctionalInterface 注解
public interface Predicate
  • 此 Predicate 接口中存在的功能方法如下:
boolean Test(T t) ;
  • 它返回一个组合谓词,表示这个谓词和另一个谓词的逻辑 AND。在评估组合谓词时,如果此谓词为假,则不评估另一个谓词。
  • 在谓词接口中,Test() 是唯一没有编写任何默认实现的方法。那么现在,’ element -> element%2 == 0 ‘ 如何映射到 Predicate 接口的实现。
  • 我们有一个方法test()接受一个接口Predicate作为参数,然后我们只能将该接口的实现的对象作为参数传递给该方法。

示例 2:

Java

// Java Program to Implementation of the Predicate interface
  
// Importing input output classes
import java.io.*;
// Importing classes from java.util package
import java.util.List;
import java.util.function.Predicate;
  
// Class 1
// helper class
// Implementation of Predicate interface
class EvenNumberPredicate implements Predicate {
  
    // Implementing all unimplemented method of the
    // Predicate interface.
    // @Override
    public boolean test(Integer number)
    {
  
        // Returns true for Even and false for Odd
        return number % 2 == 0;
    }
}
  
// Class 2
// Main class
class GFG {
  
    // Main driver method
    public static void main(String[] args)
    {
  
        // 1. Creating List of integers then
        // 2. Converting list to stream further
        // 3. Passing the object of Predicate to the filter
        // mehtod
        List.of(12, 34, 67, 19, 32, 4)
            .stream()
            .filter(new EvenNumberPredicate())
            .forEach(
                element -> System.out.println(element));
    }
}
输出
12
34
32
4

当我们将EvenNumberPredicate()的对象作为参数传递给 filter 方法时,它所做的是对传递给它的流的每个元素,它会检查EvenNumberPredicate()的重写 test() 方法中提供的条件,并且它如果 test() 返回 true,则将元素包含到返回流中,否则,如果 test() 方法返回 false,则拒绝将元素包含到返回流中。例如:对于元素 12, test()方法返回 true,因此它包含在返回流中,而对于元素 67,test() 返回 false,因此返回流中不包含 67。示例 2 准确地显示了当我们将一些逻辑传递给 filter() 方法时发生的情况。这意味着,当我们将一些逻辑传递给 filter() 方法时,后台的Java编译器会创建函数式接口的实现。

在这种情况下(即 filter()),我们告诉编译器,在 Predicate 的情况下,它采用唯一未实现的方法 test() 并提供在 filter 方法中编写的逻辑作为它的实现。