日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

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

發(fā)布時間:2023/12/3 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 函数式编程 示例_功能Java示例 第1部分–从命令式到声明式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

java 函數(shù)式編程 示例

功能編程(FP)的目的是避免重新分配變量,避免可變的數(shù)據(jù)結(jié)構(gòu),避免狀態(tài)并全程支持函數(shù)。 如果將功能性技術(shù)應(yīng)用于日常Java代碼,我們可以從FP中學(xué)到什么?

在這個名為“ Functional Java by Example”的系列文章中,我將分8步重構(gòu)現(xiàn)有代碼,以查看是否可以用Java達(dá)到Functional Nirvana 。

我對Haskell或F#等“真正的”功能語言沒有太多經(jīng)驗,但是我希望在每篇文章中以示例方式演示將這些實踐中的一些應(yīng)用于每天的Java代碼意味著什么。

希望最后您獲得了一些見識,并且知道選擇一些有益于您自己的代碼庫的技術(shù)。

這些都是這些部分:

  • 第1部分–從命令式到聲明式
  • 第2部分–命名事物
  • 第3部分–不要使用異常來控制流程
  • 第4部分–首選不變性
  • 第5部分–將I / O移到外部
  • 第6部分–用作參數(shù)
  • 第7部分–將失敗也視為數(shù)據(jù)
  • 第8部分–更多純函數(shù)

我將在每篇文章發(fā)表時更新鏈接。 如果您通過內(nèi)容聯(lián)合組織來閱讀本文,請查看我博客上的原始文章。

每次代碼也被推送到這個GitHub項目 。

免責(zé)聲明:代碼是用Apache的Groovy中 ,主要是為簡潔,所以我不必鍵入的東西(你知道:打字),其中不要緊的例子。 第二,這門語言只是讓我開心。

為什么要關(guān)心函數(shù)式編程(FP)?

如果您不是在時髦的實時流數(shù)據(jù)事件處理框架上執(zhí)行Haskell,F#或Scala,則最好打包。 這些天,甚至JavaScript的人都在圍繞您的方法旋轉(zhuǎn)函數(shù)-這種語言已經(jīng)存在了一段時間。

那里有很多文章和視頻,使您相信,如果這些天沒有跳上功能性潮流,那么您會被舊的OOP束縛所拋棄,坦率地說,它們會在幾年內(nèi)過時。

好吧,我在這里告訴您這不是完全正確的,但是FP 確實有一些前提,例如可讀性,可測試性和可維護(hù)性 ,我們也在我們的(企業(yè))Java代碼中力求實現(xiàn)的值正確嗎?

在閱讀本文時,多年以來,您可能已經(jīng)對FP是前進(jìn)還是后退或2017-2018年年期失敗表達(dá)了相同的直率觀點,您只是愿意接受新想法

通過學(xué)習(xí)FP,您可以提高每種語言的技能。

確定自己是什么,你可以從中學(xué)到如何自己編程可以從中受益。

如果您能勝任這項任務(wù),那么讓我們從...開始

現(xiàn)有的一些代碼

關(guān)于示例代碼的一句話:為這樣的博客提供人為的示例是非常棘手的:它應(yīng)該足夠容易吸引廣泛的受眾,應(yīng)該足夠簡單,無需太多上下文就可以理解,但仍然足夠有趣以至于導(dǎo)致理想的學(xué)習(xí)效果。

展望未來,本系列的每一期將以前一期為基礎(chǔ)。 下面是我們將作為起點的代碼。

因此,戴上眼鏡,看看您是否熟悉下面的編碼樣式。

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對象列表進(jìn)行處理。 文件?

嘗試弄清楚這里發(fā)生了什么

..

..

..

做完了嗎

讀這樣的東西有時會使您感到自己像一個解析器。

掃描類名( FeedHandler? )和一個方法( void handle )可以使您感到有些FeedHandler? ,從而使您感到FeedHandler? 。

但是,弄清楚在handle方法中確切“處理”了什么要困難得多。

  • 那里有一個for-loop -但是到底是在迭代什么? 多少次?
  • 調(diào)用此變量webservice ,返回稱為resource 。
  • 如果webservice成功返回,則正在迭代的doc (文檔?)將更新為狀態(tài)。
  • 似乎webservice還可以拋出一個Exception ,它被捕獲和文檔與其他狀態(tài)更新。
  • 最終,該文檔被此documentDb實例“更新”。 看起來像一個數(shù)據(jù)庫。
  • 等等,這僅適用于“重要”文檔 -在進(jìn)行上述所有操作之前,首先檢查doc.type 。

也許,您聽說過以下短語:

讀取的代碼多于編寫的代碼。

看看這塊美麗:

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

上面的代碼以命令式的方式編寫,這意味著操作狀態(tài)和行為的具體語句被明確地寫出。

  • 用零初始化一個int i
  • 當(dāng)int i小于changes列表的大小時循環(huán)
  • 每次迭代以1遞增int i

用這種命令式 (過程)編碼風(fēng)格(大多數(shù)主流語言,包括Java,C ++,C#等面向?qū)ο缶幊?#xff08;OOP)語言,都被設(shè)計為主要支持),開發(fā)人員編寫了計算機(jī)所需的確切語句。執(zhí)行以完成特定任務(wù)。

一些非常命令性 (過程性)代碼的信號:

  • 專注于如何執(zhí)行任務(wù)
  • 狀態(tài)更改和執(zhí)行順序很重要
  • 許多循環(huán)和條件
  • 該代碼明確地側(cè)重于“如何”,這使“什么”難以確定。

    專注于什么

    就像本文的標(biāo)題已經(jīng)不一樣,我們的第一步是從命令式的編碼和重構(gòu)方法轉(zhuǎn)變?yōu)楦呗暶餍缘臉邮?FP是一種形式。

    這個循環(huán)最困擾我。

    這是代碼的新版本。

    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' }再次涉及文檔集合本身- 意思是“查找所有重要的文檔,并僅返回那些重要文檔的新集合”
    • 強(qiáng)制性的for-loop (帶有中間的i變量)已由文檔集合本身上的聲明性的each方法所取代- 表示“為列表中的每個文檔執(zhí)行一段代碼,我不在乎您如何執(zhí)行” &#55357;&#56898;

    不用擔(dān)心each和findAll :這些方法是Groovy所添加的,我將它們與Java在同一代碼庫中愉快地一起使用,添加到了任何Set(例如Set,List,Map)中。 Vanilla Java 8具有等效的機(jī)制,例如forEach可以更聲明性地迭代集合。

    導(dǎo)致可讀軟件的原因是:

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

    如果我以更加實用的方式編寫代碼,就可以輕松地看到發(fā)生了什么,這可以節(jié)省我的時間 (因為是的,我90%的時間都在讀取代碼而不是編寫代碼),并且這樣編寫代碼不容易出錯 ,因為更少的行會減少隱藏錯誤的機(jī)會。

    現(xiàn)在就這樣

    在第2部分中,我們將正確命名事物 ,為更多功能的編程鋪平道路,例如在本系列的后續(xù)版本中,“ Either”或“ Try”。

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

    java 函數(shù)式編程 示例

    總結(jié)

    以上是生活随笔為你收集整理的java 函数式编程 示例_功能Java示例 第1部分–从命令式到声明式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。