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 函数式编程 示例

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

  1. java 函数式编程 示例_功能Java示例 第8部分–更多纯函数

    java 函数式编程 示例 这是第8部分,该系列的最后一部分称为"示例功能Java". 我在本系列的每个部分中开发的示例是某种"提要处理程序",用于处理文档. ...

  2. java 示例_功能Java示例 第4部分–首选不变性

    java 示例 这是称为" Functional Java by Example"的系列文章的第4部分. 在上一部分中,我们讨论了一些副作用,并且我想进一步详细说明如何通过将不可变 ...

  3. java 示例_功能Java示例 第3部分–不要使用异常来控制流程

    java 示例 这是称为" Functional Java by Example"的系列文章的第3部分. 我在本系列的每个部分中开发的示例是某种"提要处理程序" ...

  4. 大数据 java 代码示例_功能Java示例 第7部分–将失败也视为数据

    大数据 java 代码示例 这是称为" Functional Java by Example"的系列文章的第7部分. 我在本系列的每个部分中开发的示例是某种"提要处理程序 ...

  5. java 示例_功能Java示例 第5部分–将I / O移到外部

    java 示例 这是称为" Functional Java by Example"的系列文章的第5部分. 在上一部分中,我们停止了对文档的变异,并返回了数据的副本. 现在,我们需要 ...

  6. java 示例_功能Java示例 第2部分–讲故事

    java 示例 这是称为" Functional Java by Example"的系列文章的第2部分. 我在本系列的每个部分中开发的示例是某种"提要处理程序" ...

  7. Java并发编程实战_福州java编程实战培训班排名

    如何选择福州java培训中心? 在福州,如果想迅速掌握java开发,参加福州java培训班无疑是一种非常有效的方式.但是,市场上有这么多的java培训机构,我们在选择的时候难免会眼花缭乱.福州java ...

  8. java逻辑编程题_用Java编程解决一道逻辑推理题

    package mytest; import java.util.Scanner; public class Test14 { /** * 竞赛结果表明,他们都说对了一半,说错了一半,并且无并列名次, ...

  9. java软件编程学习班_高新区java软件编程 学习班

    高新相关题的可的问有利于你开发环境那些能和解决这样真正中去怪怪奇奇. 不能当基派生类的类时操作适应,程学或者说,程学需要的操派生类就基类重载作,被用象的操的对于操基类作能作派生类,多态的背的所有操:派 ...

最新文章

  1. NBT-新年4篇35分文章聚焦宏基因组研究
  2. Jeff Dean谈2020年机器学习趋势:多任务和多模式学习将成为突破口
  3. 通过 UDP 发送数据的简单范例
  4. C#简单操作MongoDB
  5. html5和前端精要(4)-头部信息
  6. 搜索引擎基础概念(1)—— 倒排索引
  7. 那些年,我们见过的 Java 服务端“问题”
  8. 【SQL那些事】事务
  9. .net System.Web.Mail发送邮件
  10. 【我的物联网成长记2】设备如何进行选型?
  11. 阿里云 linux 挂载数据盘
  12. 90 后美女学霸:出身清华姚班,成斯坦福 AI 实验室负责人高徒!
  13. springboot批量更新实体_springboot快速集成swagger
  14. 张小龙 4 小时演讲没时间看?看这一篇就够了!「附赠张小龙历年演讲实录 PDF」...
  15. 【idea插件开发】从0入门idea插件开发,idea插件开发教程,如何开发idea插件
  16. html添加悬浮图片,HTML5和jQuery制作网页灰度图片悬浮效果_js
  17. iPhone信号强度显示----信号格与数字之间的相互切换
  18. ffmpeg sdk 视频合成 音视频截取
  19. 关于网线需要知道的知识
  20. typeahead有什么作用_typeahead.js 运用教程小结

热门文章

  1. P7077-函数调用【拓扑排序,dp】
  2. 平板游戏问题(luogu 2003/2018 特长生 T4)
  3. 纪中B组模拟赛总结(2020.2.1)
  4. 初一模拟赛总结(5.18)
  5. 动态规划训练21 [FatMouse and Cheese HDU - 1078 ]
  6. 再有人问你volatile是什么,就把这篇文章发给他
  7. 一文告诉你 Java RMI 和 RPC 的区别
  8. Java 8 新特性:扩展注解(类型注解和重复注解)
  9. SSH(Spring+Struts2+Hibernate)框架搭建步骤(含配置文件以及运行结果)
  10. 阅读器关闭时尝试调用Read无效时的解决方法