如何让自己写的代码像诗一样优雅?
bigegpt 2024-10-12 06:07 7 浏览
今天是刘小爱自学Java的第50天。
感谢你的观看,谢谢你。
话不多说,开始今天的学习:
?
一、Stream流引入
这个流和IO流中的流很容易弄混淆。
但是它们是两个完全不一样的概念,Stream流是容器处理的简易API,使用起来特别方便。
用例子来说明,现有一个需求:
班上有很多同学,每个人都有自己的名字,要求找出姓刘并且名字是三个字的同学。
1常规方法
①添加元素
既然有多个元素,那需要使用到集合。
利用工具类Collections的addAll()方法可以一次性添加很多元素,我这边作为例子就只写了三个名字。
②过滤条件一:姓刘
- 使用增强for循环遍历list集合
- 同时对遍历的每一个元素使用if条件判断:name.startsWith(“刘”)
- 将满足条件的元素添加进filterlist1集合
③过滤条件二:名字为3个字
同样的道理:
- 使用增强for循环遍历filterlist1集合
- 同时对遍历的每一个元素使用if条件判断:name.length()==3
- 将满足条件的元素添加进filterlist2集合
实际上过滤条件还可以一直写下去,我这篇幅受限就只写了2个过滤条件。
④将过滤好的元素遍历打印
上述例子中,打印就能得到“刘小爱”。
2使用Stream流
这就是stream流,比用增强for循环是不是简化了很多?
特别是我所举的例子还只有2个过滤条件,若是有3个4个甚至更多,越能看出stream流的简洁之处。
该功能是在Java 8中,因为增加了lambda所带来的函数式编程,从而才引入了Stream概念。
Stream就好比在构建模型:关注做什么,而不是怎么做
- for循环的语法就是“怎么做”
- for循环的循环体才是“做什么”
①过滤出姓刘的元素
②过滤出长度为3的元素
③打印集合元素
这些就是做什么,至于具体是怎么做出来的,Stream流中不关注,并且使用stream流会让代码看上去也特优雅:
如果用普通方法,一共要6个增强for循环,使用Steam流只要6句话,就像诗一样。
①延迟方法:filter方法
该方法只是在构建模型,并不是立即执行。
只有当执行终结方法的时候,这些过滤条件才会启动。
并且支持链式编程,可以一直调用下去。
- 普通链式编程:每一步都会执行;
- 流式编程:一路构建模型,但是暂不执行,最终一并执行。
②终结方法:forEach方法
该方法是在模型执行,会立即执行得到的结果。
不支持链式编程,该方法也就意味着Stream流的结束。
二、Stream流的获取
Stream是一个最常用的流接口。
不过要注意它并不是一个函数式接口。
它主要用于容器:也就是各种集合和数组。
①集合获取流
单列集合Collecion及其实现类,直接调用steam方法就可以获取。
双列集合Map及其实现类,因为是双列集合一个元素有两个值,要先将其转换成单列集合再获取流:
- Map中的keySet,调用stream方法可以获取流。
- Map中的entrySet,调用stream方法可以获取流。
②数组获取流
数组和集合有一定的区别,它没法直接调用一个方法,所以需要使用Stream.of()来获取。
of方法是Stream接口中的一个静态方法,可以用接口名直接调用,数组只需要作为参数就好了。
三、Stream流常用方法
流模型的常用方法可以被分成两种:
- 终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持链式调用。
- 非终结方法:返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。
1终结方法
上述例子中我们接触过filter方法就是一个终结方法,除了它之外还有一个count方法。
①普通方法遍历
这个很基础,直接增强for循环遍历就可以了。
但是这有一个问题,将代码又写死了,拓展性就很差,毕竟遍历方式有很多种。
②使用流遍历
使用流遍历的话,我们只构建模型(也就是要做什么),具体是怎么遍历出来的不清楚。
需要我们去翻源码,不同地流有不同的遍历方法,这是Java开发人员已经编写好的。
为何要这样做?
为了增加代码拓展性,毕竟遍历方式又不是只有增强for循环。
③再次使用流遍历
不同的Stream流有不同的遍历方法,可以千变万化。
④count方法
这个很好理解,count,总数的意思,也就是统计容器中元素的数量。
- 数组array:也就相当于array.length
- 集合list:也就相当于list.size()
有的时候这两种方法还会弄混,count方法的好处在于,不管是数组还是集合,只用count就可以了。
说白了,Java开发人员搞出这个Stream流,都是为了简化代码,让使用Java的人写起代码来更加地简洁。
2非终结方法
①过滤:filter方法
源码:Stream<T>filter(Predicate<? super T> predicate)
参数:Predicate接口,昨天学的一个函数式接口。
面向函数编程思想:
也就是说,我们写在filter方法中的lambda表达式本质上就是对Predicate接口中的test方法的重写。
作用:
- 根据Predicate方法产的boolean值结果,代表指定的条件是否满足。
- 如果结果为true,那么将会保留该元素;
- 如果结果为false,那么将会舍弃该元素。
②取用前几个:limit方法
源码:Stream<T>limit(long maxSize)
参数:long基本数据类型
作用:
- limit方法可以对流进行截取,只取用前n个;
- 如果集合当前长度大于参数则进行截取;
- 如果越界了,就不进行操作,不会出现异常。
③跳过前几个:skip方法
源码: Stream<T>skip(long n);
参数:也是基本数据类型long
作用:
- skip方法获取一个截取之后的新流,跳过前几个元素
- 如果流的当前长度大于n,则跳过前n个;
- 如果越界了,将会得到一个长度为0的空流。
④映射:map方法
看下它的源码:
参数:Function接口,昨天学的一个函数式接口。
T类型就是Stream流中的元素类型,R类型是新生成的Stream流中的元素类型。
同样的道理:
也就是说,我们写在map方法中的lambda表达式本质上就是对Function接口中的apply方法的重写。
作用:可以将一种T类型转换成为R类型,而这种转换的动作,就称为“映射”。
⑤组合:concat方法
该方法是静态方法,使用Stream直接调用。
源码:static <T>Stream<T>concat(Stream<? extends T> a, Stream<? extends T> b)
参数:Stream接口。
作用:将几个流合并成为一个流。
总结
谢谢你的观看。
如果可以的话,麻烦帮忙点个赞,谢谢你。
相关推荐
- Go语言泛型-泛型约束与实践(go1.7泛型)
-
来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...
- golang总结(golang实战教程)
-
基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...
- Go 官宣:新版 Protobuf API(go pro版本)
-
原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...
- Golang开发的一些注意事项(一)(golang入门项目)
-
1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...
- golang 托盘菜单应用及打开系统默认浏览器
-
之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...
- golang标准库每日一库之 io/ioutil
-
一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...
- 文件类型更改器——GoLang 中的 CLI 工具
-
我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...
- Go (Golang) 中的 Channels 简介(golang channel长度和容量)
-
这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...
- Golang引入泛型:Go将Interface「」替换为“Any”
-
现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...
- 一文带你看懂Golang最新特性(golang2.0特性)
-
作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...
- Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移
-
以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...
- Golang使用grpc详解(golang gcc)
-
gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...
- Etcd服务注册与发现封装实现--golang
-
服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...
- Golang:将日志以Json格式输出到Kafka
-
在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...
- 如何从 PHP 过渡到 Golang?(php转golang)
-
我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)