函数式编程(JAVA)——Stream流

概述

Java8的Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合或数组进行链状流式的操作。可以更方便的让我们对集合或数组操作。

下述所有测试代码源码地址:https://gitee.com/ArnoldSu/functionalProgramming.git

初始化之后所有演示代码需要用到的数据集合。

public static User createUser() {return new User().setId(RandomUtil.randomLong()).setAge(RandomUtil.randomInt(0, 100)).setName(RandomUtil.randomString("澄邈德泽海超海阳海荣海逸海昌瀚钰瀚文涵亮涵煦明宇涵衍浩皛浩波浩博浩初浩宕浩歌浩广浩邈浩气浩思浩言鸿宝鸿波鸿博鸿才鸿畅鸿畴鸿达鸿德鸿飞鸿风鸿福鸿光鸿晖鸿朗鸿文鸿轩鸿煊鸿骞鸿远鸿云鸿哲鸿祯鸿志鸿卓嘉澍光济澎湃彭泽鹏池鹏海浦和浦泽瑞渊越泽博耘德运辰宇辰皓辰钊辰铭辰锟辰阳辰韦辰良辰沛晨轩晨涛晨濡晨潍鸿振吉星铭晨起运运凡运凯运鹏运浩运诚运良运鸿运锋运盛运升运杰运珧运骏运凯运乾维运运晟运莱运华耘豪星爵星腾星睿星泽星鹏星然震轩震博康震震博振强振博振华振锐振凯振海振国振平昂然昂雄昂杰昂熙昌勋昌盛昌淼昌茂昌黎昌燎昌翰晨朗德明德昌德曜范明飞昂高旻晗日昊然昊天昊苍昊英昊宇昊嘉昊明昊伟昊硕昊磊昊东鸿晖鸿朗华晖金鹏晋鹏敬曦景明景天景浩俊晖君昊昆琦昆鹏昆纬昆宇昆锐昆卉昆峰昆颉昆谊昆皓昆鹏昆明昆杰昆雄昆纶鹏涛鹏煊曦晨曦之新曦旭彬旭尧旭鹏旭东旭炎炫明宣朗学智轩昂彦昌曜坤曜栋曜文曜曦曜灿曜瑞智伟智杰智刚智阳昌勋昌盛昌茂昌黎昌燎昌翰晨朗昂然昂雄昂杰昂熙范明飞昂高朗高旻德明德昌德曜智伟智杰智刚智阳瀚彭旭炎宣朗学智昊然昊天昊苍昊英昊宇昊嘉昊明昊伟鸿朗华晖金鹏晋鹏敬曦景明景天景浩景行景中景逸景彰昆鹏昆明昆杰昆雄昆纶鹏涛鹏煊景平俊晖君昊昆琦昆鹏昆纬昆宇昆锐昆卉昆峰昆颉昆谊轩昂彦昌曜坤曜文曜曦曜灿曜瑞曦晨曦之新曦鑫鹏旭彬旭尧旭鹏旭东浩轩浩瀚浩慨浩阔鸿熙鸿羲鸿禧鸿信泽洋泽雨哲瀚胤运佑运允晨运恒运发云天耘志耘涛振荣振翱中震子辰晗昱瀚玥瀚昂瀚彭景行景中景逸景彰绍晖文景曦哲永昌子昂智宇智晖晗日晗昱瀚昂昊硕昊磊昊东鸿晖绍晖文昂文景曦哲永昌子昂智宇智晖浩然鸿运辰龙运珹振宇高朗景平鑫鹏昌淼炫明昆皓曜栋文昂治汇", 2)).setNickname(RandomUtil.randomString("风雨踏梦行  樱花味女孩  柠檬泪  日之夕矣  半世浮生  逆水寒  雨后初晴  陌路  不缺友人  听风说旧人  舟不渡我  哑剧  沫丶白色控  傻子快来~  厌己  森屿海巷  断桥再见  坚毅之梦  щǒ冇寎  遗忘  梦想的翅膀  捂着心脏说胃疼  南巷孤猫i  手捧阳光  樱花涵  指尖微凉°  你给的承诺丶早已泛黄  尐懒蟲ゞ  坚强的另一个名字叫苦撑  孤街浪人  瞌睡虫  薄荷凉  孤魄  热巴  温柔似你眉眼  离心咒ゝ  那一抹浅笑隱藏忧伤  盛夏北梦初心未改  幸福式梦想※  唯念  依然血红。  沦陷的痛", 5)).setSex(RandomUtil.randomInt(0, 2)).setDep(createDepartment());}public static List<Department> createDepartment() {List<Department> departments = new ArrayList<Department>();int i = RandomUtil.randomInt(1, 4);for (int j = 0; j < i; j++) {departments.add(new Department().setId(RandomUtil.randomLong()).setName(RandomUtil.randomString("人事技术前台前端后端", 2)).setCode(RandomUtil.randomInt(1, 10000)).setParentId(RandomUtil.randomLong(1, 10000)));}return departments;}public static List<User> initUsers = new ArrayList<User>();@BeforeAllpublic static void init() {for (int i = 0; i < 10; i++) {initUsers.add(createUser());}}

常用操作

filter

可以对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。

eg:过滤用户年龄大于80岁的人并且打印。

    /*** description Stream filter 对流中的参数进行条件过滤(过滤用户年龄大于80岁的人并且打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void filterTest() {initUsers.stream().filter(user -> user.getAge() > 80).forEach(user -> System.out.println(user.toString()));}

map

可以把对流中的元素进行计算或转换。

eg: 通过map获取用户的姓名并且遍历打印。

 /*** description Stream map 对流中的参数进行计算和转换(通过map获取用户的姓名并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void mapTest() {initUsers.stream().map(User::getName).forEach(userName -> System.out.println(userName));}

distinct

可以去除流中的重复元素。

eg:通过map获取用户的姓名去重并且遍历打印。

   /*** description Stream distinct 对流中的参数进行去重(通过map获取用户的姓名去重并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void distinctTest() {List<User> users = new ArrayList<>();users.add(new User().setName("重复名称").setAge(1));users.add(new User().setName("重复名称").setAge(2));users.stream().map(User::getName).distinct().forEach(userName -> System.out.println(userName));}

注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。

sorted

可以对流中的元素进行排序。

eg: 通过用户的年龄升序排序并且遍历打印。

/*** description Stream sorted 对流中的参数进行排序(通过用户的年龄升序排序并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void sortedTest() {initUsers.stream().sorted(Comparator.comparingInt(User::getAge)).forEach(user -> System.out.println(user));}/*** description Stream limit 设置流的最大长度,超出的部分将被抛弃(获取三个用户信息并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void limitTest() {initUsers.stream().limit(3).forEach(user -> System.out.println(user));}

注意:如果调用空参的sorted()方法,需要流中的元素是实现了Comparable。

limit

可以设置流的最大长度,超出的部分将被抛弃。

eg:获取三个用户信息并且遍历打印。

      /*** description Stream limit 设置流的最大长度,超出的部分将被抛弃(获取三个用户信息并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void limitTest() {initUsers.stream().limit(3).forEach(user -> System.out.println(user));}

skip

跳过流中的前n个元素,返回剩下的元素。

eg:跳过前五个用户输出剩下的用户信息并且遍历打印。

/*** description Stream skip 跳过流中的前n个元素,返回剩下的元素。(跳过前五个用户输出剩下的用户信息并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void skipTest() {initUsers.stream().skip(5).forEach(user -> System.out.println(user));}

flatMap

map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。

eg:输出用户下的部门信息并且遍历打印。

/*** description Stream flatMap map只能把一个对象转换成另一个对象来作为流中的元素。* 而flatMap可以把一个对象转换成多个对象作为流中的元素。(输出用户下的部门信息并且遍历打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void flatMapTest() {initUsers.stream().flatMap(user -> user.getDep().stream()).forEach(department -> System.out.println(department));}

count

可以用来获取当前流中元素的个数。

eg:获取stream中的元素个数并且打印。

/*** description Stream count 可以用来获取当前流中元素的个数。(获取stream中的元素个数并且打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void countTest() {System.out.println(initUsers.stream().count());}

max&min

可以用来或者流中的最值。

eg:获取用户年龄最大的人/最小年龄人。

/*** description Stream max/min 可以用来获取当前流中元素最值大和最小。(获取用户年龄最大的人/最小年龄人)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void maxOrMinTest() {Optional maxOptional = initUsers.stream().max(Comparator.comparing(User::getAge));System.out.println(maxOptional.get());Optional minOptional = initUsers.stream().min(Comparator.comparing(User::getAge));System.out.println(minOptional.get());}

collect

collect基础用法

把当前流转换成一个集合。

eg:获取用户的昵称转集合并且遍历输出打印。

/*** description Stream collect 把当前流转换成一个集合。(获取用户的昵称转集合并且遍历输出打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void collectTest() {initUsers.stream().map(User::getNickName).collect(Collectors.toList()).stream().forEach(nickName -> System.out.println(nickName));}

List 转 Map的常用四种用法

         //List 转 Map的常用四种用法://第⼀种: 取list中某2个字段作为Map的K,VMap<String, Integer> map1 = initUsers.stream().collect(Collectors.toMap(User::getNickName, User::getAge));map1.forEach((key, value) -> System.out.println(key + "=====" + value));//第⼆种:将id和实体Bean做为K,VMap<String, User> map2 = initUsers.stream().collect(Collectors.toMap(User::getNickName, user -> user));map2.forEach((key, value) -> System.out.println(key + "=====" + value));//第三种: key存在重复记录时处理Map<String, User> map3 = initUsers.stream().collect(Collectors.toMap(User::getNickName, Function.identity(), (key1, key2) -> key2));map3.forEach((key, value) -> System.out.println(key + "=====" + value));//第四种: 使⽤某个具体的Map类来保存,如保存时使⽤LinkedHashMapMap<String, User> map4 = initUsers.stream().collect(Collectors.toMap(User::getNickName, Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));map4.forEach((key, value) -> System.out.println(key + "=====" + value));

anyMatch

用来判断是否有任意符合匹配条件的元素,结果为boolean类型。

eg:判断是否有用户年龄大于90岁人员。

/*** description Stream anyMatch 用来判断是否有任意符合匹配条件的元素,结果为boolean类型。(判断是否有用户年龄大于90岁人员)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void anyMatchTest() {System.out.println(initUsers.stream().anyMatch(user -> user.getAge() > 90));}

allMatch

用来判断是否都符合匹配条件,结果为boolean类型。如果都符合结果为true,否则结果为false。

eg:判断是否所有用户年龄大于60岁人员。

/*** description Stream allMatch 可以用来判断是否都符合匹配条件,结果为boolean类型。如果都符合结果为true,否则结果为false。(判断是否所有用户年龄大于60岁人员)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void allMatchTest() {System.out.println(initUsers.stream().allMatch(user -> user.getAge() > 60));}

noneMatch

判断流中的元素是否都不符合匹配条件。如果都不符合结果为true,否则结果为false

eg:判断是否所有用户年龄都不大于98岁人员。

/*** description Stream noneMatch 判断流中的元素是否都不符合匹配条件。如果都不符合结果为true,否则结果为false。(判断是否所有用户年龄都不大于98岁人员)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void noneMatchTest() {System.out.println(initUsers.stream().noneMatch(user -> user.getAge() > 98));}

findAny

获取流中的任意一个元素。

eg:随机获取一个人员信息并且打印。

/*** description Stream findAny 获取流中的任意一个元素。(随机获取一个人员信息并且打印)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void findAnyTest() {System.out.println(initUsers.stream().findAny());}

findFirst

获取流中的第一个元素。

eg:获取人员中岁数最小的一个人员信息。

/*** description Stream findFirst 获取流中的第一个元素。(获取人员中岁数最小的一个人员信息)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void findFirstTest() {System.out.println(initUsers.stream().sorted(Comparator.comparing(User::getAge)).findFirst().get());}

reduce

对流中的数据按照你指定的计算方式计算出一个结果。

reduce的作用是把stream中的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值进行计算,计算结果再和后面的元素计算。

eg:计算所有用户的年龄之和。

/*** description Stream reduce 对流中的数据按照你指定的计算方式计算出一个结果。(计算所有用户的年龄之和)** @param* @return void* @author Arnold* @date 2022/6/7**/@Testpublic void reduceTest() {System.out.println(initUsers.stream().mapToInt(User::getAge).reduce(0, Integer::sum));}

注意事项

  • 流是一次性的(一旦一个流对象经过一个终结操作后。这个流就不能再被使用)
  • 不会影响原数据(我们在流中可以多数据做很多处理。但是正常情况下是不会影响原来集合中的元素的。这往往也是我们期望的)

函数式编程(JAVA)——Stream流相关推荐

  1. JUC源码级学习(下)-函数式编程、stream流、jvm等

    12.四大函数式接口(必需掌握) 新时代的程序员:lambda表达式.链式编程.函数式接口.Stream流式计算 函数式接口: 只有一个方法的接口 @FunctionalInterface publi ...

  2. Java函数式编程学习——Stream流

    目录 概述 案例数据准备 1. 常用操作 2. 中间操作 filter map distinct sorted limit skip flatMap 3. 终结操作 foreach count max ...

  3. Java8函数式编程、Stream流、Option的使用,一篇足够了

    为什么要学 大数量下处理集合效率高 代码可读性高 消灭嵌套地狱 // 查询未成年作家的评分在70以上的书籍 List<Book> bookList = new ArrayList<& ...

  4. 【深入理解函数式编程】stream流式提取字符串中数字

    问题 字符串处理是日常开发中接触最频繁的一种,如何从字符串中提取符合特定条件的信息则是更为频繁.本文介绍一种利用stream方式来提取字符串中数字的方法,供学习借鉴和参考,以便今后能够加以应用. 方法 ...

  5. java8函数式编程之Stream流处理的方法和案例讲解

    函数式编程最早是数学家阿隆佐·邱奇研究的一套函数变换逻辑,又称Lambda Calculus(λ-Calculus),所以也经常把函数式编程称为Lambda计算. 为什么Java需要Lambda表达式 ...

  6. Java Stream流总结

    Java8新增的Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利. 文章目录 前言 一.stream是什么? 二.使用步骤 1.得到sream 2 ...

  7. java Stream 流

    java Stream 流 Stream 流 流的创建 流的转化 Optianal 流的计算 Stream 流 1. Stream的定义 来自数据源的支持聚合操作的元素序列. 即一个流对外提供接口,接 ...

  8. 测试Java Stream流 parralle与 sequential的效率

    测试Java Stream流 parralle与 sequential的效率 实验环境 操作系统:win10 处理器:Intel i5-4200U 2核4线程 Java版本:1.8 实验方案 统计大小 ...

  9. Java stream流式计算详解

    Java stream流式计算详解 1. Stream概述 1.1 Stream简介 1.2 Stream分类 2. Stream操作 2.1 Stream创建 2.2 Stream无状态操作 2.3 ...

  10. Java Stream流基础

    Java Stream流基础 何为Steam流? Stream 是对集合数组对象功能的增强,其专注于对集合数组对象进行各种非常便利.高效的聚合操作,或者大批量数据操作.通常我们需要多行代码才能完成的操 ...

最新文章

  1. 让炼丹师不再为数据集发愁,这家公司建了一个AI公开数据集平台
  2. Ardino基础教程 13_温度传感器
  3. 动态规划解题套路框架
  4. 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。
  5. numpy的where方法
  6. linux方面的杂谈
  7. 博途v14电脑要求_博图TIA V14版本完整体验加测试
  8. 实验七-卷积编码的MATLAB实现
  9. C语言-快速排序实现
  10. 建筑灭火器配置设计规范
  11. 模拟游戏在设计上是如何处理对仿真性的追求的?
  12. oracle资产负债表重分类吗,资产负债表必须重分类的吗
  13. 计算机网络自顶向下-套接字编程作业
  14. win10 git bash 设置别名
  15. PWM控制直流电机的正转、反转、加速和减速
  16. 互联网时代:天才与伟人的区别
  17. C++单个类的所有对象是否共享虚函数表的验证
  18. 短信发送平台-阿里大于
  19. YUV 转 RGB快速算法
  20. java反射课程一:基本API使用

热门文章

  1. Lua学习笔记--table
  2. 容器存储卷的介绍与使用
  3. 关于 BBBB 站视频删除问题解释
  4. 原生图片预览实现及由此引出的图片自适应宽高问题探索
  5. 虚拟主机和服务器有啥区别,虚拟主机和服务器的区别在哪?
  6. 音视频开发--音视频基础
  7. 获得淘宝商品详情高级版api接口
  8. 倒计时代码(用户输入秒数直接转换为时分秒)
  9. Win10自带照片查看器卸载了怎么找回来
  10. python 围棋按照坐标查找棋子_python 实现围棋游戏(纯tkinter gui)