java 函数式编程 示例_功能Java示例 第1部分–从命令式到声明式

java 函数式编程 示例

功能编程(FP)的目的是避免重新分配变量,避免可变的数据结构,避免状态并全程支持函数。 如果将功能性技术应用于日常Java代码,我们可以从FP中学到什么?

在这个名为“ Functional Java by Example”的系列文章中,我将分8步重构现有代码,以查看是否可以用Java达到Functional Nirvana

我对Haskell或F#等“真正的”功能语言没有太多经验,但是我希望在每篇文章中以示例方式演示将这些实践中的一些应用于每天的Java代码意味着什么。

希望最后您获得了一些见识,并且知道选择一些有益于您自己的代码库的技术。

这些都是这些部分:

  • 第1部分–从命令式到声明式
  • 第2部分–命名事物
  • 第3部分–不要使用异常来控制流程
  • 第4部分–首选不变性
  • 第5部分–将I / O移到外部
  • 第6部分–用作参数
  • 第7部分–将失败也视为数据
  • 第8部分–更多纯函数

我将在每篇文章发表时更新链接。 如果您通过内容联合组织来阅读本文,请查看我博客上的原始文章。

每次代码也被推送到这个GitHub项目 。

免责声明:代码是用Apache的Groovy中 ,主要是为简洁,所以我不必键入的东西(你知道:打字),其中不要紧的例子。 第二,这门语言只是让我开心。

为什么要关心函数式编程(FP)?

如果您不是在时髦的实时流数据事件处理框架上执行Haskell,F#或Scala,则最好打包。 这些天,甚至JavaScript的人都在围绕您的方法旋转函数-这种语言已经存在了一段时间。

那里有很多文章和视频,使您相信,如果这些天没有跳上功能性潮流,那么您会被旧的OOP束缚所抛弃,坦率地说,它们会在几年内过时。

好吧,我在这里告诉您这不是完全正确的,但是FP 确实有一些前提,例如可读性,可测试性和可维护性 ,我们也在我们的(企业)Java代码中力求实现的值正确吗?

在阅读本文时,多年以来,您可能已经对FP是前进还是后退或2017-2018年年期失败表达了相同的直率观点,您只是愿意接受新想法

通过学习FP,您可以提高每种语言的技能。

确定自己是什么,你可以从中学到如何自己编程可以从中受益。

如果您能胜任这项任务,那么让我们从...开始

现有的一些代码

关于示例代码的一句话:为这样的博客提供人为的示例是非常棘手的:它应该足够容易吸引广泛的受众,应该足够简单,无需太多上下文就可以理解,但仍然足够有趣以至于导致理想的学习效果。

展望未来,本系列的每一期将以前一期为基础。 下面是我们将作为起点的代码。

因此,戴上眼镜,看看您是否熟悉下面的编码样式。

class FeedHandler {Webservice webserviceDocumentDb documentDbvoid handle(List<Doc> changes) {for (int i = 0; i < changes.size(); i++) {def doc = changes[i]if (doc.type == 'important') {try {def resource = webservice.create(doc)doc.apiId = resource.iddoc.status = 'processed'} catch (e) {doc.status = 'failed'doc.error = e.message}documentDb.update(doc)}}}
}
  • 这是某种FeedHandler
  • 它有两个属性,一些Webservice类和DocumentDb类。
  • 有一个handle方法可以对Doc对象列表进行处理。 文件?

尝试弄清楚这里发生了什么

..

..

..

做完了吗

读这样的东西有时会使您感到自己像一个解析器。

扫描类名( FeedHandler? )和一个方法( void handle )可以使您感到有些FeedHandler? ,从而使您感到FeedHandler?

但是,弄清楚handle方法中确切“处理”了什么要困难得多。

  • 那里有一个for-loop -但是到底是在迭代什么? 多少次?
  • 调用此变量webservice ,返回称为resource
  • 如果webservice成功返回,则正在迭代的doc (文档?)将更新为状态。
  • 似乎webservice还可以抛出一个Exception ,它被捕获和文档与其他状态更新。
  • 最终,该文档被此documentDb实例“更新”。 看起来像一个数据库。
  • 等等,这仅适用于“重要”文档 -在进行上述所有操作之前,首先检查doc.type

也许,您听说过以下短语:

读取的代码多于编写的代码。

看看这块美丽:

for (int i = 0; i < changes.size(); i++) {

上面的代码以命令式的方式编写,这意味着操作状态和行为的具体语句被明确地写出。

  • 用零初始化一个int i
  • int i小于changes列表的大小时循环
  • 每次迭代以1递增int i

用这种命令式 (过程)编码风格(大多数主流语言,包括Java,C ++,C#等面向对象编程(OOP)语言,都被设计为主要支持),开发人员编写了计算机所需的确切语句。执行以完成特定任务。

一些非常命令性 (过程性)代码的信号:

  1. 专注于如何执行任务
  2. 状态更改和执行顺序很重要
  3. 许多循环和条件

该代码明确地侧重于“如何”,这使“什么”难以确定。

专注于什么

就像本文的标题已经不一样,我们的第一步是从命令式的编码和重构方法转变为更具声明性的样式-FP是一种形式。

这个循环最困扰我。

这是代码的新版本。

class FeedHandler {Webservice webserviceDocumentDb documentDbvoid handle(List<Doc> changes) {// for (int i = 0; i < changes.size(); i++) {//    def doc = changes[i]changes.findAll { doc -> doc.type == 'important' }.each { doc ->try {def resource = webservice.create(doc)doc.apiId = resource.iddoc.status = 'processed'} catch (e) {doc.status = 'failed'doc.error = e.message}documentDb.update(doc)}}
}

有什么变化?

  • if (doc.type == 'important')部分已替换为findAll { doc -&gt; doc.type == 'important' } if (doc.type == 'important') findAll { doc -&gt; doc.type == 'important' } findAll { doc -&gt; doc.type == 'important' }再次涉及文档集合本身- 意思是“查找所有重要的文档,并仅返回那些重要文档的新集合”
  • 强制性的for-loop (带有中间的i变量)已由文档集合本身上的声明性的each方法所取代- 表示“为列表中的每个文档执行一段代码,我不在乎您如何执行” &#55357;&#56898;

不用担心eachfindAll :这些方法是Groovy所添加的,我将它们与Java在同一代码库中愉快地一起使用,添加到了任何Set(例如Set,List,Map)中。 Vanilla Java 8具有等效的机制,例如forEach可以更声明性地迭代集合。

导致可读软件的原因是:

描述“什么”而不是“如何”

如果我以更加实用的方式编写代码,就可以轻松地看到发生了什么,这可以节省我的时间 (因为是的,我90%的时间都在读取代码而不是编写代码),并且这样编写代码不容易出错 ,因为更少的行会减少隐藏错误的机会。

现在就这样

在第2部分中,我们将正确命名事物 ,为更多功能的编程铺平道路,例如在本系列的后续版本中,“ Either”或“ Try”。

翻译自: https://www.javacodegeeks.com/2017/11/functional-java-example-part-1-imperative-declarative.html

java 函数式编程 示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

su联合推拉插件_[实习小记一一SU建模]

鉴于本菜鸡在实习阶段一直在SU建模&#xff0c;那就讲讲我在SU建模的心路历程吧。本菜鸡之前还是SU小白时(俗称白斩鸡&#xff0c;并且现在也很白)&#xff0c;只会死命地用推拉。来到公司初探SU,第一个高层建筑便花费我半个月的时间(我突然想起有一篇日记特别好笑我是个SU人&a…

Linux 命令之 tar 命令-打包和备份的归档工具(附压缩/解压工具)

文章目录一、命令介绍二、命令语法三、常用选项四、命令示例&#xff08;一&#xff09;对指定的目录进行打包&#xff08;即备份归档&#xff09;&#xff0c;不压缩&#xff08;二&#xff09;对指定目录下的内容&#xff08;不含目录本身&#xff09;进行打包&#xff08;即…

纹理和基元_通过粘性仙人掌基元进行延迟加载和缓存

纹理和基元您显然知道什么是延迟加载 &#xff0c;对吗&#xff1f; 而且您无疑知道缓存 。 据我所知&#xff0c;Java中没有一种优雅的方法来实现它们中的任何一个。 这是我在Cactoos原语的帮助下为自己找到的。 Matteo Garrone的《 Reality》&#xff08;2012年&#xff09;…

oracle 造数据脚本_Oracle数据库shell脚本--统计所有数据库用户信息及明细

概述今天主要分享一下两个shell脚本&#xff0c;主要是为了查看所有数据库用户及其表空间&#xff0c;统计某个指定用户的明细&#xff0c;下面一起来看看吧~数据库连接脚本use script settdb.sh for DB login details registry#!/bin/bashtmp_username$SH_USERNAMEtmp_passwor…

学维修电脑要多久_学厨师要多久才出师

学厨师一般要学多久&#xff1f;以苏州新东方学厨师为例&#xff1a;厨师培训可以分为长期、短期。中餐、西餐、西点长期专业学习时间1-3年不等&#xff1b;短期专业从7天到8个月不等&#xff0c;主要是按学习内容来划分&#xff0c;比如学苏式汤面&#xff0c;只需要半个月左右…

Linux 命令之 rpm -- RPM 软件包的管理工具

文章目录一、命令介绍二、语法结构三、常用选项用于查询和检查包用于安装、升级和删除包用于执行其他功能四、命令示例&#xff08;一&#xff09;查询和检查包1. 查看一个已安装包的信息&#xff08;版本、用途等&#xff09;2. 查看与指定程序相关的所有安装文件3. 查看一个已…

react核心虚拟dom_使用虚拟时间测试基于时间的React堆核心流

react核心虚拟domReactor Core实现了Reactive Streams规范&#xff0c;并处理了&#xff08;可能无限的&#xff09;数据流。 如果您感兴趣&#xff0c;请查看它提供的出色文档 。 在这里&#xff0c;我假设对Reactor Core库的Flux和Mono类型有一些基本的了解&#xff0c;并且将…

图书管理系统python语言-Python简易版图书管理系统

本文实例为大家分享了python图书管理系统的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 """ 图书管理系统 """ import random # books{书名:剩余数量, 书名:剩余数量} import time books {"防脱发指南": 5, "颈椎康…

docker 打包mysql_基于docker部署mysql的数据持久化问题

本人最近在使用docker部署mysql时&#xff0c;在持久化mysql数据时遇到了一个有趣的问题&#xff0c;将排查过程及思考记录在这里&#xff0c;以备后查。先简单描述下我遇到的问题&#xff1a;在mysql容器中创建了两个数据库&#xff0c;然后使用docker commit想要保存容器的修…

Linux 命令之 ls -- 列出指定目录下的内容

文章目录一、命令介绍二、语法格式三、常用选项四、参考示例&#xff08;一&#xff09;显示工作目录下&#xff08;当前目录&#xff09;所有的文件和目录&#xff08;二&#xff09;显示工作目录下所有的文件和目录&#xff08;三&#xff09;显示文件的详细信息&#xff0c;…

kotlin dsl_Spring Webflux – Kotlin DSL –实现的演练

kotlin dsl在以前的博客文章中&#xff0c;我描述了Spring Web Framework中的响应式编程支持Spring Webflux如何使用基于Kotlin的DSL使用户能够以非常直观的方式描述路由。 在这里&#xff0c;我想探索一些底层实现。 描述一组端点的样本DSL看起来像这样&#xff1a; package…

cad调了比例因子没反应_「室内设计」大神们都在用的9个CAD制图技巧,你会用几个?...

1、快捷特性面板如何调取&#xff1f;2、 如何快速恢复上一次删除物体&#xff1f;3、 如何快速关闭监视注释器&#xff1f;4、如何快速处理重复碎线&#xff1f;5、如何解决虚线在模型空间和布局空间显示不一致的问题&#xff1f;6、 如何快速更改图块名称&#xff1f;7、 PL线…

ubuntu 12下的apache+php+mysql_老司机传授Ubuntu下Apache+PHP+MySQL环境搭建攻略

一、首先安装MySql&#xff1a;对于MySql来讲在整个过程中是相对独立的安装&#xff0c;并且我的ubuntu在以前做开发的时候就已经安装了MySql&#xff0c;所以以下只给出安装步骤&#xff1a;1、安装MySql的服务&#xff1a;sudo apt-get install mysql-server要注意的是安装过…

Linux 命令之 mv -- 移动文件/重命名文件

文章目录命令介绍语法格式常用选项命令示例&#xff08;一&#xff09;文件重命名&#xff08;二&#xff09;目录重命名&#xff08;三&#xff09;移动目录&#xff08;四&#xff09;移动目录且重命名&#xff08;五&#xff09;将一个目录下的内容移动到另外一个目录下&…

jax-rs jax-ws_迟来总比没有好:SSE或服务器发送的事件现在已在JAX-RS中

jax-rs jax-ws服务器发送的事件 &#xff08;或简称为SSE &#xff09;是非常有用的协议&#xff0c;它允许服务器通过HTTP将数据推送到客户端。 这是我们的Web浏览器支持的年龄&#xff0c;但是令人惊讶的是&#xff0c; JAX-RS规范在很长一段时间内都忽略了这一点。 尽管Jers…

根据录入的计算公式计算_小规模纳税人增值税计算公式是什么,什么人能被称为小规模纳税人?- 理财技巧...

摘要&#xff1a; 想必大家都知道小规模纳税人在增值税的缴纳上能够享受到不少的优惠措施和政策&#xff0c;最终可以少交不少钱&#xff01;那么什么人能被称为小规模纳税人呢&#xff1f;小规模纳税人增值税计算公式又是什么呢&#xff1f;下面赢家财富网就带大家详细了解一下…

Linux 命令之 chmod -- 改变文件或目录权限

文章目录一、命令介绍二、语法格式三、常用选项四、权限表达式&#xff08;一&#xff09;采用权限字母和操作符表达式&#xff08;二&#xff09;采用权限数字表达式五、参考示例&#xff08;一&#xff09;为拥有者、所属群组以及其他人添加关于directory1的读、写和执行权限…

12章总结

一.集合类概述 java.util包中提供了一些集合类&#xff0c;这些集合类又被称为容器。 集合类与数组的不同之处&#xff1a; 数组的长度是固定的&#xff0c;集合的长度是可变的&#xff1a;数组用来存放基本类型的数据&#xff0c;集合用来存放对象的引用。 常…

java亮剑_黄金矿工3-太空版

快速搜索机型:诺基亚 N70系列(176208)7610 3230 6600 6260 6620 6630 6670 6680 6681 6682 N70 N72 ;松下: X700 X800 ;联想: P930诺基亚 N73系列(240320)N73 5320 5320XM 5320di_XM 5630XM 5700 5700XM 5710XM 5730XM 6110 6110N 6120 6120C 6120ci 6121 6122C 6124C 6210S 62…

怎么知道跟交换机互联的交换机_怎么选择POE交换机

工作的呢&#xff1f;48V供电的就是标准PoE吗&#xff1f;下面我们简单讲解一下标准PoE和MCU PoE交换机&#xff08;单片机&#xff09;及非标PoE设备是怎么工作的。标准PoE和MCU PoE交换机&#xff08;单片机&#xff09;以及非标准PoE产品定义首先我们来看一下什么是标准PoE、…