函数式编程-Stream流
1. 概述
1.1 为什么学?
能够看懂公司里的代码
大数量下处理集合效率高
代码可读性高
消灭嵌套地狱
//查询未成年作家的评分在70以上的书籍 由于洋流影响所以作家和书籍可能出现重复,需要进行去重 List<Book> bookList = new ArrayList<>(); Set<Book> uniqueBookValues = new HashSet<>(); Set<Author> uniqueAuthorValues = new HashSet<>(); for (Author author : authors) {if (uniqueAuthorValues.add(author)) {if (author.getAge() < 18) {List<Book> books = author.getBooks();for (Book book : books) {if (book.getScore() > 70) {if (uniqueBookValues.add(book)) {bookList.add(book);}}}}} } System.out.println(bookList);
List<Book> collect = authors.stream().distinct().filter(author -> author.getAge() < 18).map(author -> author.getBooks()).flatMap(Collection::stream).filter(book -> book.getScore() > 70).distinct().collect(Collectors.toList()); System.out.println(collect);
1.2 函数式编程思想
1.2.1 概念
面向对象思想需要关注用什么对象完成什么事情。而函数式编程思想就类似于我们数学中的函数。它主要关注的是对数据进行了什么操作。
1.2.2 优点
代码简洁,开发快速
接近自然语言,易于理解
易于"并发编程"
2. Lambda表达式
2.1 概述
Lambda是JDK8中一个语法糖。他可以对某些匿名内部类的写法进行简化。它是函数式编程思想的一个重要体现。让我们不用关注是什么对象。而是更关注我们对数据进行了什么操作。
2.2 核心原则
可推导可省略
2. 3 基本格式
(参数列表)->{代码}
例一
我们在创建线程并启动时可以使用匿名内部类的写法:
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("你知道吗 我比你想象的 更想在你身边");} }).start();
可以使用Lambda的格式对其进行修改。修改后如下:
new Thread(()->{System.out.println("你知道吗 我比你想象的 更想在你身边"); }).start();
例二:
现有方法定义如下,其中IntBinaryOperator是一个接口。先使用匿名内部类的写法调用该方法。
public static int calculateNum(IntBinaryOperator operator){int a = 10;int b = 20;return operator.applyAsInt(a, b);} public static void main(String[] args) {int i = calculateNum(new IntBinaryOperator() {@Overridepublic int applyAsInt(int left, int right) {return left + right;}});System.out.println(i);}
Lambda写法:
public static void main(String[] args) {int i = calculateNum((int left, int right)->{return left + right;});System.out.println(i);}
例三:
现有方法定义如下,其中IntPredicate是一个接口。先使用匿名内部类的写法调用该方法。
public static void printNum(IntPredicate predicate){int[] arr = {1,2,3,4,5,6,7,8,9,10};for (int i : arr) {if(predicate.test(i)){System.out.println(i);}}}public static void main(String[] args) {printNum(new IntPredicate() {@Overridepublic boolean test(int value) {return value%2==0;}});}
Lambda写法:
public static void main(String[] args) {printNum((int value)-> {return value%2==0;});}public static void printNum(IntPredicate predicate){int[] arr = {1,2,3,4,5,6,7,8,9,10};for (int i : arr) {if(predicate.test(i)){System.out.println(i);}}}
例四:
现有方法定义如下,其中Function是一个接口。先使用匿名内部类的写法调用该方法。
public static <R> R typeConver(Function<String,R> function){String str = "1235";R result = function.apply(str);return result;}public static void main(String[] args) {Integer result = typeConver(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.valueOf(s);}});System.out.println(result);}
Lambda写法:
Integer result = typeConver((String s)->{return Integer.valueOf(s);});System.out.println(result);
例五:
现有方法定义如下,其中IntConsumer是一个接口。先使用匿名内部类的写法调用该方法。
public static void foreachArr(IntConsumer consumer){int[] arr = {1,2,3,4,5,6,7,8,9,10};for (int i : arr) {consumer.accept(i);}}public static void main(String[] args) {foreachArr(new IntConsumer() {@Overridepublic void accept(int value) {System.out.println(value);}});}
Lambda写法:
public static void main(String[] args) {foreachArr((int value)->{System.out.println(value);});}
2.4 省略规则
参数类型可以省略
方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
方法只有一个参数时小括号可以省略
以上这些规则都记不住也可以省略不记
3. Stream流
3.1 概述
Java8的Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合或数组进行链状流式的操作。可以更方便的让我们对集合或数组操作。
3.2 案例数据准备
(导入依赖) <dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency></dependencies>
@Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode//用于后期的去重使用 public class Author {//idprivate Long id;//姓名private String name;//年龄private Integer age;//简介private String intro;//作品private List<Book> books; }
@Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode//用于后期的去重使用 public class Book {//idprivate Long id;//书名private String name; //分类private String category; //评分private Integer score; //简介private String intro; }
private static List<Author> getAuthors() {//数据初始化Author author = new Author(1L,"蒙多",33,"一个从菜刀中明悟哲理的祖安人",null);Author author2 = new Author(2L,"亚拉索",15,"狂风也追逐不上他的思考速度",null);Author author3 = new Author(3L,"易",14,"是这个世界在限制他的思维",null);Author author4 = new Author(3L,"易",14,"是这个世界在限制他的思维",null); //书籍列表List<Book> books1 = new ArrayList<>();List<Book> books2 = new ArrayList<>();List<Book> books3 = new ArrayList<>(); books1.add(new Book(1L,"刀的两侧是光明与黑暗","哲学,爱情",88,"用一把刀划分了爱恨"));books1.add(new Book(2L,"一个人不能死在同一把刀下","个人成长,爱情",99,"讲述如何从失败中明悟真理")); books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));books2.add(new Book(3L,"那风吹不到的地方","哲学",85,"带你用思维去领略世界的尽头"));books2.add(new Book(4L,"吹或不吹","爱情,个人传记",56,"一个哲学家的恋爱观注定很难把他所在的时代理解")); books3.add(new Book(5L,"你的剑就是我的剑","爱情",56,"无法想象一个武者能对他的伴侣这么的宽容"));books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?"));books3.add(new Book(6L,"风与剑","个人传记",100,"两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢?")); author.setBooks(books1);author2.setBooks(books2);author3.setBooks(books3);author4.setBooks(books3); List<Author> authorList = new ArrayList<>(Arrays.asList(author,author2,author3,author4));return authorList;}
3.3 快速入门
3.3.1 需求
我们可以调用getAuthors方法获取到作家的集合。现在需要打印所有年龄小于18的作家的名字,并且要注意去重。
3.3.2 实现
//打印所有年龄小于18的作家的名字,并且要注意去重List<Author> authors = getAuthors();authors.stream()//把集合转换成流.distinct()//先去除重复的作家.filter(author -> author.getAge()<18)//筛选年龄小于18的.forEach(author -> System.out.println(author.getName()));//遍历打印名字
3.4 常用操作
3.4.1 创建流
单列集合: 集合对象.stream()
List<Author> authors = getAuthors();Stream<Author> stream = authors.stream();
数组:Arrays.stream(数组)
或者使用Stream.of
来创建
Integer[] arr = {1,2,3,4,5};Stream<Integer> stream = Arrays.stream(arr);Stream<Integer> stream2 = Stream.of(arr);
双列集合:转换成单列集合后再创建
Map<String,Integer> map = new HashMap<>();map.put("蜡笔小新",19);map.put("黑子",17);map.put("日向翔阳",16); Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
3.4.2 中间操作
filter
可以对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。
例如:
打印所有姓名长度大于1的作家的姓名
List<Author> authors = getAuthors();authors.stream().filter(author -> author.getName().length()>1).forEach(author -> System.out.println(author.getName()));
map
可以把对流中的元素进行计算或转换。
例如:
打印所有作家的姓名
List<Author> authors = getAuthors(); authors.stream().map(author -> author.getName()).forEach(name->System.out.println(name));
// 打印所有作家的姓名List<Author> authors = getAuthors(); // authors.stream() // .map(author -> author.getName()) // .forEach(s -> System.out.println(s)); authors.stream().map(author -> author.getAge()).map(age->age+10).forEach(age-> System.out.println(age));
distinct
可以去除流中的重复元素。
例如:
打印所有作家的姓名,并且要求其中不能有重复元素。
List<Author> authors = getAuthors();authors.stream().distinct().forEach(author -> System.out.println(author.getName()));
注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。
待更新
函数式编程-Stream流相关推荐
- JAVA学习 API_day11(属性集, 函数式编程, stream流)
属性集, 函数式编程, stream流 I/O流小结 1. 属性集 2. 函数式编程 3. stream流 I/O流小结 文件复制: BufferedInputStream/BufferedOutpu ...
- 函数式编程-Stream流(来源三更草堂)
函数式编程-Stream流 1. 概述 1.1 为什么学? 能够看懂公司里的代码 大数量下处理集合效率高 代码可读性高 消灭嵌套地狱 //查询未成年作家的评分在70以上的书籍 由于洋流影响所以作家和书 ...
- 函数式编程-Stream流/lambda表达式/Optional/函数式接口/方法引用/高级用法
函数式编程-Stream流 不会Lambda表达式.函数式编程?你确定能看懂公司代码?-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂 1. 概述 ...
- Java8函数式编程——Stream流
函数式编程-Stream流 实例练习:https://javadaily.cn/post/2022020817/7f222b3057fb/ 1. 概述 1.1 为什么学? 能够看懂公司里的代码 大数量 ...
- java学习笔记20(Lambda表达式、函数式编程、流式计算、练习)
文章目录 11.3 学习内容 Lambda表达式 Lambda标准格式 格式说明 省略规则 使用前提 函数式接口 预定义的函数式接口 工作内容 任务1 总结&明日计划 11.4 学习内容 流式 ...
- Lambda表达式接口更新方法引用函数式接口Stream流
Lambda表达式&接口更新&方法引用&函数式接口&Stream流 Lambda 1.程序启动三种不同的表现形式 2.Lambda表达式的标准格式 3.练习 Lambd ...
- 【Java】Java函数式编程以及流的操作
文章目录 大纲 lambda表达式 一般内部类 局部内部类 匿名内部类 基于函数式接口的lambda表达式 JDK8中自带的函数式接口 Predicate判断 Consumer消费 Supplier供 ...
- jdk8銝要onematch_JDK 8 新特性之函数式编程 → Stream API
开心一刻 今天和朋友们去K歌,看着这群年轻人一个个唱的贼嗨,不禁感慨道:年轻真好啊! 想到自己年轻的时候,那也是拿着麦克风不放的人 现在的我没那激情了,只喜欢坐在角落里,默默的听着他们唱,就连旁边的妹 ...
- 【CSDN软件工程师能力认证学习精选】 Java8新特性学习-函数式编程(Stream/Function/Optional/Consumer)
CSDN软件工程师能力认证是由CSDN制定并推出的一个能力认证标准,宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备, ...
最新文章
- Linux 下安装matlab2014a
- VMware View 5.0 Ready! 资源汇总(持续更新)
- 远程监督关系抽取漫谈:结合知识图谱和图神经网络
- 英语口语 week13 Monday
- Paypal 在线支付接口应用从零开始,第2节,[支付API原理及流程]
- mysql 递归查询树型结构_MySQL递归查询所有子节点,树形结构查询
- 入门机器学习(九)--应用机器学习的建议
- 深度学习制作数据集的部分代码实现(解压zip、生成json文件)
- ajax怎样带值,ajax携带状态值
- chainmaker 交易执行失败也会打包到区块 落盘
- Hello World 我的第一个VB程序
- 单元在整体坐标系下的刚度矩阵
- pytest文档24-fixture的作用范围(scope)
- 温暖和暖和的区别Java_国内冬天哪里比较暖和 冬天暖和的城市排名
- 何时需要对时间序列进行Log Transformation
- 第一次学游泳技巧_第一次学游泳作文8篇
- mysql constant number,Mysql报Too many connections,不要乱用ulimit了,看看如何正确修改进程的最大文件数...
- SAM-DETR源码讲解
- 跨域(cross-domain)访问 cookie (读取和设置)
- 让你分分钟学会qt视频播放器
热门文章
- 【js html】对于img图片的引用填充,src可以给什么值?
- 华为nova8se和华为nova7pro哪个好-哪个更值得入手-参数对比
- 详解CorelDRAW X7的多种视图显示模式
- 3000字梳理大数据开发流程及规范(建议收藏)
- 中国土地市场网爬虫案例
- 阵列信号DOA估计系列(二).导向矢量与空间FFT(附代码)
- 开源免费Webrtc转发服务器Mediasoup的概念解释与基本介绍(一)
- Redis 3.0集群搭建/配置/FAQ
- 基于php鲜花花卉销售商城网站(源码+系统+mysql数据库+Lw文档)
- 前端提效 - js 批量导出 excel 为zip压缩包