Java 流filter()

原文:https://www.studytonight.com/java-examples/java-stream-filter

Java 中的是元素或对象的序列。 Java 8 引入流。它们允许我们以高效的方式对数据源执行各种操作。

在本教程中,我们将学习如何在 Java 中过滤流。

流过滤器()方法

Streams 的filter()方法允许我们基于一个条件或一个谓词来过滤一个给定的流。

请注意,此方法不会改变给定的流。它将返回一个包含满足条件的元素的新流。该方法的签名如下所示。

Stream<T> filter(Predicate<? super T> condition)

让我们看几个例子来了解它的工作原理。

示例 1:用 Java 过滤流

让我们从一个流中过滤掉所有大于 7 的元素。我们将从列表中创建一个流,然后在这个流上应用filter()方法。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Demo
{
    public static void main(String[] args)
    {
        List<Integer> list = Arrays.asList(7, 9, 1, 2, 5, 11, 21);
        System.out.println("The List is: " + list);

        Predicate<Integer> numGreaterThanSeven = p -> (p > 7);//Writing the condition or Predicate

        Stream<Integer> s = list.stream();//Stream of the list
        Stream<Integer> filteredStream = s.filter(numGreaterThanSeven);

        System.out.println("Filtered Elements are: ");
        filteredStream.forEach(System.out :: println);
    }
}

列表为:【7、9、1、2、5、11、21】 过滤元素为: 9 11 21

示例 2:过滤用户数据流

让我们处理一个用户定义的类。我们将创建下面定义的学生类。

class Student
{
    private String name;
    private int regNo;
    private Double gpa;

    Student(String s, int i, Double gpa)
    {
        this.name = s;
        this.regNo = i;
        this.gpa = gpa;
    }    
    //Getters and Setters
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getRegNo() {
        return regNo;
    }
    public void setRegNo(int regNo) {
        this.regNo = regNo;
    }
    public Double getGpa() {
        return gpa;
    }
    public void setGpa(Double gpa) {
        this.gpa = gpa;
    }    
}

让我们过滤掉所有 GPA 大于 8 的学生。我们将为此条件创建一个谓词,并将其与 filter()方法一起使用。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class Demo
{
    public static void main(String[] args)
    {
        Student s1 = new Student("Jack", 102, 8.55);
        Student s2 = new Student("Joe", 101, 8.75);
        Student s3 = new Student("Clay", 107, 9.1);
        Student s4 = new Student("Simon", 105, 7.99);
        Student s5 = new Student("Reacher", 103, 7.00);

        List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);

        Predicate<Student> gpaGreaterThanEight = c -> c.getGpa() > 8.0;//Lambda expression for Predicate

        Stream filteredStream = list.stream().filter(gpaGreaterThanEight);
    }
}

我们还可以在 Student 类中定义一个返回布尔值的方法。然后,我们可以将此方法直接与 filter()方法一起使用。我们将使用 collect()方法将过滤后的流收集到一个列表中。

public boolean gpaGreaterThanEight()
{
    return this.getGpa() > 8.0;
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{
    public static void main(String[] args)
    {
        Student s1 = new Student("Jack", 102, 8.55);
        Student s2 = new Student("Joe", 101, 8.75);
        Student s3 = new Student("Clay", 107, 9.1);
        Student s4 = new Student("Simon", 105, 7.99);
        Student s5 = new Student("Reacher", 103, 7.00);

        List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
        System.out.println("The Student List is: ");
        for(Student s : list)
            System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());

        Stream filteredStream = list.stream().filter(Student :: gpaGreaterThanEight);//Class Method for Predicate 
        List<Student> filteredList = (List<Student>) filteredStream.collect(Collectors.toList());

        System.out.println("\nThe Filtered List is: ");
        for(Student s : filteredList)
            System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
    }
}

学生名单为: 杰克 102 8.55 乔 101 8.75 克莱 107 9.1 西蒙 105 7.99 雷彻 103 7.0 T7【过滤名单为: 杰克 102 8.55 乔 101 8.75 克莱 107 9.1

示例 3:使用 Lambda 表达式过滤流

我们也可以使用多个条件进行过滤。这些条件可以使用谓词中的Lambda 表达式来创建。或者我们可以在用户定义的类中创建一个方法(如果我们使用的是用户定义的类)。让我们继续前面的例子,过滤掉所有 GPA 大于 8 且姓名正好包含三个字符的学生。

让我们首先使用一个 Lambda 表达式来完成我们的任务。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{
    public static void main(String[] args)
    {
        Student s1 = new Student("Jack", 102, 8.55);
        Student s2 = new Student("Joe", 101, 8.75);
        Student s3 = new Student("Clay", 107, 9.1);
        Student s4 = new Student("Simon", 105, 7.99);
        Student s5 = new Student("Reacher", 103, 7.00);

        List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
        System.out.println("The Student List is: ");
        for(Student s : list)
            System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());

        Predicate<Student> p = c -> (c.getGpa() > 8.0) && (c.getName().length() == 3);

        Stream filteredStream = list.stream().filter(p);
        List<Student> filteredList = (List<Student>) filteredStream.collect(Collectors.toList());

        System.out.println("\nThe Filtered List is: ");
        for(Student s : filteredList)
            System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
    }
}

学生名单为: 杰克 102 8.55 乔 101 8.75 克莱 107 9.1 西蒙 105 7.99 雷彻 103 7.0 T7】过滤名单为: 乔 101 8.75

让我们在 Student 类中定义一个方法来检查这两个条件,并相应地返回一个布尔值。

public boolean predicateCondition()
{
    if(this.getGpa() > 8.0 && this.getName().length() == 3)
        return true;
    else
        return false;
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{
    public static void main(String[] args)
    {
        Student s1 = new Student("Jack", 102, 8.55);
        Student s2 = new Student("Joe", 101, 8.75);
        Student s3 = new Student("Clay", 107, 9.1);
        Student s4 = new Student("Simon", 105, 7.99);
        Student s5 = new Student("Reacher", 103, 7.00);

        List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
        System.out.println("The Student List is: ");
        for(Student s : list)
            System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());

        Stream filteredStream = list.stream().filter(Student :: predicateCondition);
        List<Student> filteredList = (List<Student>) filteredStream.collect(Collectors.toList());

        System.out.println("\nThe Filtered List is: ");
        for(Student s : filteredList)
            System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
    }
}

学生名单为: 杰克 102 8.55 乔 101 8.75 克莱 107 9.1 西蒙 105 7.99 雷彻 103 7.0 T7】过滤名单为: 乔 101 8.75

Lambda 表达式中的异常处理

在我们用于谓词的 Lambda 表达式中,可能会出现选中或未选中的异常。在 lambda 表达式中使用 try-catch 块来处理异常是一个好主意。

Predicate<Student> p = c ->
                   {
                       try{
                           return c.predicateCondition(); 
                       }
                       catch(Exception e) {
                           System.out.print(e);
                       }
                       return false;
                   };

我们也可以使用像 ThrowingFunction 这样的第三方库来处理被检查的异常。我们将使用这个库的抛出类。它将返回一个包装异常。

try
{
        List<Student> customersWithValidProfilePhoto = list
                      .stream()
                      .filter(ThrowingPredicate.unchecked(Student :: predicateCondition))
                      .collect(Collectors.toList());
}
catch(Exception e)
{
        System.out.print(e);
}

如果上述代码中出现异常,那么我们将得到以下输出。

pl . touk . throwing . exception . wrappedexception

摘要

流只是一系列元素。filter()方法允许我们根据条件从流中过滤出元素。条件是使用谓词定义的。我们可以使用 Lambda 表达式或类方法(对于用户定义的类)来创建谓词。谓词在确定如何过滤元素方面起着至关重要的作用。