Java Stream filter()的用法(附带实例)
filter() 方法是 Java Stream 接口提供的过滤方法。该方法可以将 lambda 表达式作为参数,然后按照 lambda 表达式的逻辑过滤流中的元素。过滤出想要的流元素后,还需使用 Stream 提供的 collect() 方法按照指定方法重新进行封装。
【实例 1】输出 1~10 的所有奇数。将 1~10 的数字放到一个 ArrayList 列表中,调用该列表的 Stream 对象的 filter() 方法,该方法的参数为过滤奇数的 lambda 表达式。查看该方法被执行完毕后 Stream 对象返回的结果。
代码在 Eclipse 中出现黄色警告,这是由 printeach(String message, List list) 方法中的 list 参数没有指定泛型引起的。但是,这也体现出 lambda 表达式可以自动识别数据类型的优点。读者可以忽略此警告。
实例 1 中演示的集合元素是数字类型,集合能保存的不止是数字,下面这个实例将演示如何利用过滤器以对象属性为条件过滤元素。
【实例 2】找出年龄大于 30 的员工。本例使用了如下定义的 Employee 类:
在获取员工集合后,将年龄大于 30 的员工过滤出来。如果将员工集合返回的流对象泛型定义为 <Employee>,就可以直接在 lambda 表达式中使用 Employee 类的方法。
【实例 1】输出 1~10 的所有奇数。将 1~10 的数字放到一个 ArrayList 列表中,调用该列表的 Stream 对象的 filter() 方法,该方法的参数为过滤奇数的 lambda 表达式。查看该方法被执行完毕后 Stream 对象返回的结果。
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FilterOddDemo {
static void printeach(String message, List list) { //输出集合元素
System.out.print(message); //输出文字信息
list.stream().forEach(n -> {
System.out.print(n + " "); //使用 forEach 方法遍历集合并输出元素
});
System.out.println(); //换行
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(); //创建空数组
for (int i = 1; i <= 10; i++) {
list.add(i); //从 1 循环到 10 //给集合赋值
}
printeach("集合原有元素:", list); //输出集合元素
Stream<Integer> stream = list.stream(); //获取集合流对象
//将集合中的所有奇数过滤出来,把过滤结果重新赋值给流对象
stream = stream.filter(n -> n % 2 == 1);
//将流对象重新封装成一个 List 集合
List<Integer> result = stream.collect(Collectors.toList());
printeach("过滤之后的集合元素:", result); //输出集合元素
}
}
运行结果如下:
集合原有元素:1 2 3 4 5 6 7 8 9 10
过滤之后的集合元素:1 3 5 7 9
List<Integer> result = list.stream().filter(n -> n % 2 == 1).collect(Collectors.toList());这种写法也可以避免终端操作造成的“流被消费掉”的问题,因为每次被操作的流都是从集合中重新获取的。
代码在 Eclipse 中出现黄色警告,这是由 printeach(String message, List list) 方法中的 list 参数没有指定泛型引起的。但是,这也体现出 lambda 表达式可以自动识别数据类型的优点。读者可以忽略此警告。
实例 1 中演示的集合元素是数字类型,集合能保存的不止是数字,下面这个实例将演示如何利用过滤器以对象属性为条件过滤元素。
【实例 2】找出年龄大于 30 的员工。本例使用了如下定义的 Employee 类:
import java.util.ArrayList;
import java.util.List;
public class Employee {
private String name; // 姓名
private int age; // 年龄
private double salary; // 工资
private String sex; // 性别
private String dept; // 部门
// 构造方法
public Employee(String name, int age, double salary, String sex, String dept) {
this.name = name;
this.age = age;
this.salary = salary;
this.sex = sex;
this.dept = dept;
}
// 重写 toString()方法,方便输出员工信息
public String toString() {
return "name=" + name + ", age=" + age + ", salary=" + salary + ", sex=" + sex + ", dept=" + dept;
}
// 以下是员工属性的 getter 方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
public double getSalary() {
return salary;
}
public String getSex() {
return sex;
}
public String getDept() {
return dept;
}
static List<Employee> getEmpList() { // 提供数据初始化方法
List<Employee> list = new ArrayList<Employee>();
list.add(new Employee("老张", 40, 9000, "男", "运营部"));
list.add(new Employee("小刘", 24, 5000, "女", "开发部"));
list.add(new Employee("大刚", 32, 7500, "男", "销售部"));
list.add(new Employee("老李", 28, 5500, "女", "销售部"));
list.add(new Employee("小马", 21, 3000, "男", "开发部"));
list.add(new Employee("老王", 35, 6000, "女", "人事部"));
list.add(new Employee("小王", 21, 3000, "女", "人事部"));
return list;
}
}
在获取员工集合后,将年龄大于 30 的员工过滤出来。如果将员工集合返回的流对象泛型定义为 <Employee>,就可以直接在 lambda 表达式中使用 Employee 类的方法。
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FilerDemo {
public static void main(String[] args) {
List<Employee> list = Employee.getEmpList(); //获取公共类的测试数据
Stream<Employee> stream = list.stream(); //获取集合流对象
stream = stream.filter(people -> people.getAge() > 30); //将年龄大于 30 岁的员工过滤出来
List<Employee> result = stream.collect(Collectors.toList()); //将流对象重新封装成一个 List 集合
for (Employee emp : result) { //遍历结果集
System.out.println(emp); //输出员工对象信息
}
}
}
运行结果如下:
name=老张, age=40, salary=9000.0, sex=男, dept=运营部
name=大刚, age=32, salary=7500.0, sex=男, dept=销售部
name=老王, age=35, salary=6000.0, sex=女, dept=人事部
ICP备案:
公安联网备案: