一、引言

在上一篇文章中《这么简单,还不会使用java8 stream流的map()方法吗?》分享了使用stream的map()方法,不知道小伙伴还有印象吗,先来回顾下要点,map()方法是把一个流中的元素T转换为另外一个新流中的元素R,转换完成后两个流的元素个数不发生改变,具体怎么使用,请小伙伴移步上篇查看。在上篇文章中遗留了一个问题,本篇文章来解决它。先来看stream的另一个API--filter()方法。

二、概述

先来看下filter方法的定义,

该方法返回一个新流,这个新流中的元素要匹配给定的表达式。从方法的入参及出参可以看到返回的新流中的元素和元素流中的元素类型是一致的,和map()方法不同的是新流的元素个数要小于等于原始流的元素个数。

下面看下示意图,更清晰,

是不是很简单,下面看下具体的用法。

三、详述

以”找出一年级的所有学生的成绩“为例,来看下怎么使用filter()方法。同样初始化五个学生,

Data.java

package com.example.log.stream.test;

import com.example.log.stream.entity.Student;
import java.util.ArrayList;
import java.util.List; /**
* @date 2022/11/30 22:43
*/
public class Data {
public static List<Student> initData(){
List<Student> students= new ArrayList<>(); Student s1=new Student();
s1.setName("王五");
s1.setSchoolClass("一年级");
s1.setChineseScore(100);
s1.setMathScore(100);
students.add(s1); Student s2=new Student();
s2.setName("李四");
s2.setSchoolClass("一年级");
s2.setChineseScore(100);
s2.setMathScore(100);
students.add(s2); Student s3=new Student();
s3.setName("李思");
s3.setSchoolClass("二年级");
s3.setChineseScore(100);
s3.setMathScore(100);
students.add(s3); Student s4=new Student();
s4.setName("王五");
s4.setSchoolClass("三年级");
s4.setChineseScore(100);
s4.setMathScore(100);
students.add(s4); Student s5=new Student();
s5.setName("赵三");
s5.setSchoolClass("一年级");
s5.setChineseScore(100);
s5.setMathScore(100);
students.add(s5);
return students;
}
}

Student.java类这里不在贴出,有兴趣的可以自己写,或参考上篇文章中的定义。直接看怎么实现。

3.1、找出一年级的所有学生成绩

要找出一年级的所有学生成绩,就要根据schoolClass进行过滤,看下使用filter()方法怎么写。

package com.example.log.stream.test;

import com.example.log.stream.entity.Student;

import java.util.List;
import java.util.stream.Collectors; /**
* 测试filter()方法
* @date 2022/12/1 21:01
*/
public class TestFilter {
public static void main(String[] args) {
List<Student> students=Data.initData();
//使用filter对schoolClass进行过滤,满足条件的返回true,否则返回false,达到过滤的目的
List<Student> firstClass=students.stream().filter(student -> {
if("一年级".equals(student.getSchoolClass())){
return true;
}
return false;
}).collect(Collectors.toList());
//打印新的流
for (Student student:firstClass) {
System.out.println(student);
}
System.out.println("---------------------");
for (Student student:students) {
System.out.println(student);
}
}
}

使用filter()方法,该方法中的函数式接口,返回一个boolean类型的值,从而决定了该元素是否会写入到新流中。看下结果,

如果现在有这样一个需求,找出所有的一年级的学生,并给他们的数学成绩都减1分。要怎么办?

3.2、给一年级的所有同学的数学成绩减1分

我们可以在上面的基础上进行修改,完成此需求,

package com.example.log.stream.test;

import com.example.log.stream.entity.Student;
import java.util.List;
import java.util.stream.Collectors;
/**
* 测试filter()方法
* @date 2022/12/1 21:01
*/
public class TestFilter {
public static void main(String[] args) {
List<Student> students=Data.initData();
//使用filter对schoolClass进行过滤,满足条件的返回true,否则返回false,达到过滤的目的
List<Student> firstClass=students.stream().filter(student -> {
if("一年级".equals(student.getSchoolClass())){
//所有一年级的学生,数学减1分
student.setMathScore(student.getMathScore()-1);
return true;
}
return false;
}).collect(Collectors.toList());
//打印新的流
for (Student student:firstClass) {
System.out.println(student);
}
System.out.println("---------------------");
for (Student student:students) {
System.out.println(student);
}
}
}

只需在上面的基础上增加一行代码即可,即符合条件的都减1分,看下打印结果。

从上面的解雇可以看到使用filter完成了该功能,但带来的一个副作用是原始数据也变了,主要是因为修改的是通过一个引用指向的对象。其实不太建议这样去写,因为filter()方法从字面意思就可以知道,它的作用就是过滤,最好不要参杂其他的逻辑,可以再加一个map()方法。

TestFilter2.java

package com.example.log.stream.test;

import com.example.log.stream.entity.Student;

import java.util.List;
import java.util.stream.Collectors; /**
* 测试filter()方法
* @date 2022/12/1 21:01
*/
public class TestFilter2 {
public static void main(String[] args) {
List<Student> students=Data.initData();
//使用filter对schoolClass进行过滤,满足条件的返回true,否则返回false,达到过滤的目的
List<Student> firstClass=students.stream().filter(student -> {
if("一年级".equals(student.getSchoolClass())){
return true;
}
return false;
}).map(student -> {//map()方法
//设置数学成绩减1
student.setMathScore(student.getMathScore()-1);
return student;
}).collect(Collectors.toList());
//打印新的流
for (Student student:firstClass) {
System.out.println(student);
}
System.out.println("---------------------");
for (Student student:students) {
System.out.println(student);
}
}
}

上面在使用完filter后,由于是一个stream流,那么继续使用map()方法,对上一步过滤出的元素再对数学成绩减1操作,最后得到结果。通过一个示意图,

这样是不是比直接在fliter()中更加清晰。

四、总结

stream的filter()方法是要通过true/false来筛选元素,为true的会放到新流中,反之为false的不会放到新流中。

推荐阅读

这么简单,还不会使用java8 stream流的map()方法吗?

有不正之处,欢迎指正,谢谢!

感谢动动小手关注公众号【良工说技术】,更多精彩不容错过。

总算给女盆友讲明白了,如何使用stream流的filter()操作的更多相关文章

  1. 【ZZ】终于有人把云计算、大数据和人工智能讲明白了!

    终于有人把云计算.大数据和人工智能讲明白了! https://mp.weixin.qq.com/s/MqBP0xziJO-lPm23Bjjh9w 很不错的文章把几个概念讲明白了...图片拷不过来... ...

  2. 没讲明白的水题orz

    有一道解释程序的水题没给非计算机专业的同学讲明白orz,在这里再练一下.. 源代码完全没有缩进真是难以忍受.. p.s.懂递归就不用看了#include <stdio.h> int n = ...

  3. [CSP-S模拟测试]:小盆友的游戏(数学 or 找规律)

    题目传送门(内部题110) 输入格式 第一行一个整数$N$,表示小盆友的个数. 第二行$N$个整数$A_i$,如果$A_i=-1$表示$i$目前是自由身,否则$i$是$A_i$的跟班. 输出格式 一个 ...

  4. Scala 深入浅出实战经典 第41讲:List继承体系实现内幕和方法操作源码揭秘

    Scala 深入浅出实战经典 第41讲:List继承体系实现内幕和方法操作源码揭秘 package com.parllay.scala.dataset /** * Created by richard ...

  5. Scala 深入浅出实战经典 第39讲:ListBuffer、ArrayBuffer、Queue、Stack操作代码实战

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  6. 云计算分布式大数据Hadoop实战高手之路第八讲Hadoop图文训练课程:Hadoop文件系统的操作实战

    本讲通过实验的方式讲解Hadoop文件系统的操作. “云计算分布式大数据Hadoop实战高手之路”之完整发布目录 云计算分布式大数据实战技术Hadoop交流群:312494188,每天都会在群中发布云 ...

  7. 第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作、增、删、改、查

    第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作.增.删.改.查 elasticsearch(搜索引擎)基本的索引 ...

  8. MEF入门之不求甚解,但力求简单能讲明白(四)

    上一篇我们已经可以获取各种FileHandler的实例和对应的元数据.本篇,我们做一个稍微完整的文件管理器. 1.修改接口IFileHandler,传入文件名 namespace IPart { pu ...

  9. 终于有人把云计算、大数据和 AI 讲明白了

    最近学习hadoop以及生态,顺便看到了这篇文章,总结的很到位,转载下. 我今天要讲这三个话题,一个是云计算,一个大数据,一个人工智能,我为什么要讲这三个东西呢?因为这三个东西现在非常非常的火,它们之 ...

  10. 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!

    系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...

随机推荐

  1. 解决Nginx+Tomcat中https转http请求问题---解决js加载使用http的问题

    解决js加载使用http的问题 控制台错误提示: Mixed Content: The page at '' was loaded over HTTPS, but requested an insec ...

  2. 安装Alertmanager,nginx配置二级路径代理访问

    安装配置 Alertmanager wget https://github.com/prometheus/alertmanager/releases/download/v0.20.0/alertman ...

  3. 我的 Kafka 旅程 - broker

    broker在kafka的服务端运行,一台服务器相当于一个broker:每个broker下可以有多个topic,每个topic可以有多个partition,在producer端可以对消息进行分区,每个 ...

  4. 分布式存储系统之Ceph集群CephFS基础使用

    前文我们了解了ceph之上的RBD接口使用相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16753098.html:今天我们来聊一聊ceph之上的另一 ...

  5. MatrixOne从入门到实践01——初识MatrixOne

    初识MatrixOne 简介 MatrixOrigin 矩阵起源 是一家数据智能领域的创新企业,其愿景是成为数字世界的核心技术提供者. 物理世界的数字化和智能化无处不在.我们致力于建设开放的技术开源社 ...

  6. .NET 7 RC 2 发布,倒计时一个月发布正式版

    微软2022-10-22 发布了 .NET 7 RC 2,下一站是.NET 7正式发布,就在下个月Net Conf 2022(11月8日)期间正式发布. 经过长达一年时间的开发,.NET 7 规划的所 ...

  7. 右击存放项目的文件夹出现 open with Visual Studio Code 的打开方式

    最终效果 步骤1: 找到 Visual Studio Code 的安装位置 (右击桌面Visual Studio Code 图标-->属性-->打开文件夹所在位置) 新建一个可以编辑的 c ...

  8. Invalid bound statement (not found)出现原因和解决方法

    Invalid bound statement (not found)出现原因和解决方法 前言: 想必各位小伙伴在码路上经常会碰到奇奇怪怪的事情,比如出现Invalid bound statement ...

  9. Can not set int field xxx to java.lang.Long 错误

    Can not set int field xxx to java.lang.Long 错误 这个错误其实是因为Java程序和MySQL表中字段的属性匹配不一致 我的报错是Can not set ja ...

  10. c语言KMP匹配算法与字符串替换算法

    一.字符串匹配算法 (1)传统匹配算法BF int Index_BF(char* S, char* T){ int i=1,j=1; while(i<=strlen(S) && ...