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 表达式或类方法(对于用户定义的类)来创建谓词。谓词在确定如何过滤元素方面起着至关重要的作用。