:傳遞給 left 或 substring 函數的長度參數無效。_Java函數式編碼結構-好程序員

  好程序員Java培訓分享Java函數式編碼結構,本文將探討三種下一代JVM語言:Groovy、Scala和Clojure,比較并對比新的功能和范例,讓Java開發人員對自己近期的未來發展有大體的認識,下面我們一起來看一下吧。

55ec17e45e7d8c1fb0e69f00db4e23f8.png

  當垃圾回收成為主流時,它消除了所有類別的難以調試的問題,使運行時能夠為開發人員管理復雜的、容易出錯的進程。函數式編程旨在為你編寫的算法實現同樣的優化,這樣你就可以從一個更高的抽象層面開展工作,同時運行時執行復雜的優化。

  Java下一代語言并不都占用從命令式到函數式的語言頻譜的同一位置,但都展現出函數功能和習語。函數式編程技術有明確定義,但語言有時為相同的函數式概念使用不同的術語,使得我們很難看到相似之處。在本期文章中,我比較了Scala、Groovy和Clojure的函數式編碼風格并討論了它們的優勢。

  命令式處理

  我要首先探討一個常見問題及其命令式解決方案。假如給定一個名稱列表,其中一些名稱包含一個字符。系統會要求你在一個逗號分隔的字符串中返回名稱,該字符串中不包含單字母的名稱,每個名稱的首字母都大寫。實現該算法的Java代碼如清單1所示。

  清單1.命令式處理

  public class TheCompanyProcess {

  public String cleanNames(List listOfNames) {

  StringBuilder result = new StringBuilder();

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

  if (listOfNames.get(i).length() > 1) {

  result.append(capitalizeString(listOfNames.get(i))).append(",");

  }

  }

  return result.substring(0, result.length() - 1).toString();

  }

  public String capitalizeString(String s) {

  return s.substring(0, 1).toUpperCase() + s.substring(1, s.length());

  }

  }

  由于你必須處理整個列表,解決清單1中問題最簡單的方式是使用一個命令式循環。對于每個名稱,都需要進行檢查,確認其長度是否大于1,然后(如果長度大于1)將首字母大寫的名稱附加到result字符串,并在后面加逗號。最終字符串中的最后一個名稱不應包含逗號,所以我將它從最后返回值中移走。

  在命令式編程中,建議你在較低級上別執行操作。在清單1中的cleanNames()方法中,我執行了三個任務:我篩選列表以消除單字符,將列表中每個名稱的首字母變換為大寫,然后將列表轉化為一個字符串。在命令式語言中,我不得不為三個任務都使用同一低級機制(對列表進行迭代)。函數式語言將篩選、變換和轉化視為常見操作,因此它們提供給你從不同視角解決問題的方式。

  函數式處理

  函數編程語言與命令式語言的問題分類方式不同。篩選、變換和轉化邏輯類別表現為函數。那些函數實現低級變換并依賴于開發人員來編寫作為參數傳遞的函數,進而定制函數的行為。我可以用偽代碼將清單1中的問題概念化為:

  listOfEmps -> filter(x.length > 1) -> transform(x.capitalize) ->

  convert(x, y -> x + "," + y)

  利用函數式語言,你可以建模這一概念性解決方案,無需擔心實現細節。

  Scala實現

  清單2使用Scala實現清單1中的處理示例。它看起來就像是前面的偽代碼,包含必要的實現細節。

  清單2.Scala處理

  val employees = List("neal", "s", "stu", "j", "rich", "bob")

  val result = employees

  .filter(_.length() > 1)

  .map(_.capitalize)

  .reduce(_ + "," + _)

  對于給定的名稱列表,我首先篩選它,剔除長度不大于1的所有名稱。然后將該操作的輸出提供給map()函數,該函數對集合的每個元素執行所提供的代碼塊,返回變換后的集合。最后,來自map()的輸出集合流向reduce()函數,該函數基于代碼塊中提供的規則將每個元素結合起來。

  在本例中,我將每對元素結合起來,用插入的逗號連接它們。我不必考慮三個函數調用中參數的名稱是什么,所以我可以使用方便的Scala快捷方式,也就是說,使用_跳過名稱。reduce()函數從前兩個元素入手,將它們結合成一個元素,成為下一個串接中的第一個元素。在“瀏覽”列表的同時,reduce()構建了所需的逗號分隔的字符串。

  我首先展示Scala實現是因為我對它的語法比較熟悉,而且Scala分別為篩選、變換和轉化概念使用了行業通用的名稱,即filter、map和reduce。

  Groovy實現

  Groovy擁有相同的功能,但對它們進行命名的方式與腳本語言(比如Ruby)更加一致。清單1中處理示例的Groovy版本如清單3所示。

  清單3.Groovy處理

  class TheCompanyProcess {

  public static String cleanUpNames(List listOfNames) {

  listOfNames

  .findAll {it.length() > 1}

  .collect {it.capitalize()}

  .join(',')

  }

  }

  盡管清單3在結構上類似于清單2中的Scala示例,但方法名稱不同。Groovy的findAll集合方法應用所提供的代碼塊,保留代碼塊為true的元素。如同Scala,Groovy包含一個隱式參數機制,為單參數代碼塊使用預定義的it隱式參數。collect方法(Groovy的map版本)對集合的每個元素執行所提供的代碼塊。Groovy提供一個函數(join()),使用所提供的分隔符將字符串集合串聯為單一字符串,這正是本示例中所需要的。

  Clojure實現

  Clojure是一個使用reduce、map和filter函數名的函數式語言,如清單4所示。

  清單4.Clojure處理示例

  (defn process [list-of-emps]

  (reduce str (interpose ","

  (map clojure.string/capitalize

  (filter #(< 1 (count %)) list-of-emps)))))

  Clojure的thread-first宏

  thread-last宏使集合的處理變得更加簡單。類似的Clojure宏thread-first可簡化與JavaAPI的交互。例如普遍的Java代碼語句person.getInformation().

  getAddress().getPostalCode(),這體現了Java違反迪米特法則的傾向。這種類型的語句給Clojure編程帶來一些煩惱,迫使使用JavaAPI的開發人員不得不構建由內而外的語句,比如(getPostalCode(getAddress(getInformationperson)))。thread-first宏消除了這一語法困擾。你可以使用宏將嵌套調用編寫為(->persongetInformationgetAddressgetPostalCode),想嵌套多少層都可以。

  如果你不習慣查看Clojure,可以使用清單4中的代碼,其結構可能不夠清晰。Clojure這樣的Lisp是“由內而外”進行工作的,所以必須從最后的參數值list-of-emps著手。Clojure的(filter)函數接受兩個參數:用于進行篩選的函數(本例中為匿名函數)和要篩選的集合。

  你可以為第一個參數編寫一個正式函數定義,比如(fn[x](<1(countx))),但使用Clojure可以更簡潔地編寫匿名函數。與前面的示例一樣,篩選操作的結果是一個較少的集合。(map)函數將變換函數接受為第一個參數,將集合(本例中是(filter)操作的返回值)作為第二個參數。Clojure的(map)函數的第一個參數通常是開發人員提供的函數,但接受單一參數的任何函數都有效;內置capitalize函數也符合要求。

  最后,(map)操作的結果成為了(reduce)的集合參數。(reduce)的第一個參數是組合函數(應用于(interpose)的返回的(str))。(interpose)在集合的每個元素之間(除了最后一個)插入其第一個參數。

  當函數嵌套過多時,即使最有經驗的開發人員也會倍感頭疼,如清單4中的(process)函數所示。所幸的是,Clojure包含的宏支持你將結構“調整”為更可讀的順序。清單5中的功能與清單4中的功能一樣。

  清單5.使用Clojure的thread-last宏

  (defn process2 [list-of-emps]

  (->> list-of-emps

  (filter #(< 1 (count %)))

  (map clojure.string/capitalize)

  (interpose ",")

  (reduce str)))

  Clojurethread-last宏采取對集合應用各種變換的常見操作并顛倒典型的Lisp的順序,恢復了從左到右的更自然的閱讀方式。在清單5中,首先是(list-of-emps)集合。代碼塊中每個隨后的表單被應用于前一個表單。Lisp的優勢之一在于其語法靈活性:任何時候代碼的可讀性變得很差時,你都可以將代碼調整回具有較高可讀性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275930.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275930.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

系統架構師學習筆記_第十一章(上)_連載

第十一章 信息安全技術 11.1 信息安全關鍵技術 11.1.1 加密和解密 有意的計算機犯罪 和 無意的數據破壞 被動攻擊&#xff1a;非法地從傳輸信道上截取信息&#xff0c;或從存儲載體上 偷竊、復制 信息。 主動攻擊&#xff1a;對傳輸或存儲的數據進行 惡意的刪除、篡改 等。 …

跨庫一致性_設計跨平臺的一致性

跨庫一致性I offended an Apple employee the other day when I was checking out the new iPad Pro and I told him that I was an Android phone user. Eyes rolled, jokes were made, and we agreed to disagree.前幾天&#xff0c;我在檢閱新iPad Pro時冒犯了一名蘋果員工&…

React-生命周期雜記

前言 自從React發布Fiber之后&#xff0c;更新速度日新月異&#xff0c;而生命周期也隨之改變&#xff0c;雖然原有的一些生命周期函數面臨廢棄&#xff0c;但理解其背后更新的機制也是一種學習 在這里根據官方文檔以及社區上其他優秀的文章進行一個對于生命周期的總結&#xf…

漫畫 | 一個NB互聯網項目的上線過程…

大家好&#xff0c;我是若川&#xff08;點這里加我微信 ruochuan12&#xff0c;長期交流學習&#xff09;。今天雖然是周六&#xff0c;但還是要上班&#xff0c;所以就推薦一篇比較輕松的漫畫。點擊下方卡片關注我、加個星標&#xff0c;或者查看源碼等系列文章。學習源碼整體…

stm32 中斷處理級別_STM32中斷優先級徹底講解

文章來源&#xff1a;http://blog.sina.com.cn/s/blog_4fed55ce0100j7nd.html一&#xff1a;綜述STM32 目前支持的中斷共為 84 個(16 個內核68 個外部)&#xff0c; 16 級可編程中斷優先級的設置(僅使用中斷優先級設置 8bit 中的高 4 位)和16個搶占優先級(因為搶占優先級最多可…

胖子臉:庫珀·布萊克100年

In 16th century Europe, roman typefaces were the first to surpass blackletter as the preferred choice for expressing emphasis in print. True bold weight roman letters didn’t appear until the 19th century, which critics quickly coined “Fat Faces” due to …

C語言中的布爾值

C語言的布爾類型在C語言標準(C89)沒有定義布爾類型&#xff0c;所以C語言判斷真假時以0為假&#xff0c;非0為真。所以我們通常使用邏輯變量的做法&#xff1a; //定義一個int類型變量&#xff0c;當變量值為0時表示false&#xff0c;值為1時表示trueint flag;flag 0;//......…

用委托實現窗體間傳值

1.新建一個工程.在Form1中添加一個Label和一個Button.新建一個事件類,讓它有一個string 類型的屬性,用于傳值. 1 ///ReturnValueEventArgs.cs 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace test 7 { 8 public class Return…

c++ explicit關鍵字_聊一聊 C++的特性 explicit 匿名空間

聊一聊 C的特性 explicit && 匿名空間explicit關鍵字首先看一下explicit的作用&#xff1a;explicit 是避免構造函數的參數自動轉換為類對象的標識符&#xff0c;平時代碼中并不是經常用到&#xff0c;但是&#xff0c;有時候就是因為這個&#xff0c;會造成一定的BUG出…

谷歌瀏覽器那些有趣的隱藏功能

大家好&#xff0c;我是若川&#xff08;點這里加我微信 ruochuan12&#xff0c;長期交流學習&#xff09;。今天推薦一篇實用文章。文末有抽獎。點擊下方卡片關注我、加個星標&#xff0c;或者查看源碼等系列文章。學習源碼整體架構系列、年度總結、JS基礎系列很多小伙伴說還是…

AppDelegate的模塊化+瘦身

前言 關于iOS的模塊化&#xff0c;要追溯到16年接觸的BeeHive了&#xff0c;BeeHive將功能模塊化&#xff0c;以module的形式進行構建&#xff0c;以performSelector&#xff1a;的形式進行module的事件響應&#xff0c;以protocol的形式進行module間的通信。可以說思路非常清晰…

yii mysql_Yii2框架操作數據庫的方法分析【以mysql為例】

本文實例講述了Yii2框架操作數據庫的方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;準備數據庫DROP TABLE IF EXISTS pre_user;CREATE TABLE pre_user(id int(11) AUTO_INCREMENT PRIMARY KEY,username varchar(255) NOT NULL,password varchar(32) NOT NULL DEF…

C++接口注意

1. 用Record接口&#xff0c;要注意 Packed的區別 2. cdecl和stdcall的區別 3. C導出的函數建議用C格式stdcall導出&#xff0c;使用Def文件定義名稱 4. 用VS寫的API dll要注意是否引用了MFC的DLL&#xff0c;否則會使LoadLibrary失敗&#xff0c;并GetLastError后返回14001 Ap…

Vue 3.1.0 的 beta 版發布

大家好&#xff0c;我是若川&#xff08;點這里加我微信 ruochuan12&#xff0c;長期交流學習&#xff09;。昨晚尤大視頻號直播說到vue 3.1.0 beta版發布了&#xff0c;今天分享這篇文章。也有小伙伴可能注意到了昨晚我一直在送禮物。點擊下方卡片關注我、加個星標&#xff0c…

設計模式練習_設計練習是邪惡的

設計模式練習It was the final round of interviews. Or, so the candidate thought.這是采訪的最后一輪。 或者&#xff0c;所以候選人認為。 She’d spent all day interviewing in our office. As the final interviewer, I walked her out the building. She seemed confi…

morningcat2018 LearningDocs

2019獨角獸企業重金招聘Python工程師標準>>> LearningDocs 學習資料與文檔 JCP&#xff08;Java Community Process &#xff0c;Java社區進程 &#xff09; https://www.jcp.org/en/home/index JSR&#xff08;Java Specification Requests&#xff0c;Java規范請求…

firefox下可惡的value

前幾天做項目 遇到這樣一個情況 document.getElementById("txtTest").value "111"; 這條語句在ff下和ie下都是好用的 但是用開發工具看html代碼 ie下顯示正常 ff下顯示的卻是修改之前的(實際上已經修改了&#xff0c;只是html沒有修改過來) 用js修改input…

據說 99% 的人不知道 vue-devtools 還能直接打開對應組件文件?本文原理揭秘

1. 前言你好&#xff0c;我是若川[1]&#xff0c;微信搜索「若川視野」關注我&#xff0c;專注前端技術分享&#xff0c;一個愿景是幫助5年內前端開闊視野走向前列的公眾號。歡迎加我微信ruochuan12&#xff0c;長期交流學習。這是學習源碼整體架構系列 之 launch-editor 源碼&…

mysql 存儲 事務_MYSQL 可以在存儲過程里實現事務控制嗎

展開全部6.7 MySQL 事務與鎖定命令6.7.1 BEGIN/COMMIT/ROLLBACK 句法缺省的&#xff0c;MySQL 運行在 autocommit 模式。這就意味著&#xff0c;當你執行完一e69da5e887aa62616964757a686964616f31333361326265個更新時&#xff0c;MySQL 將立刻將更新存儲到磁盤上。如果你使用…

如何忽略證書繼續訪問_前5個最容易被忽視的可訪問性問題

如何忽略證書繼續訪問Accessibility is quickly becoming one of the most important aspects of the way we use the web, if not the most important. Just between 2017 and 2018, the number of federal court cases regarding web accessibility nearly tripled, signifyi…