函數式編程解析:定義、功能與Java實踐

目錄

  • 一、函數式編程
    • 1.1 什么是函數式編程
    • 1.2 函數式編程特征
      • 1.2.1 純函數
      • 1.2.2 函數是一等公民
    • 1.3 函數式編程在java中的實踐
  • 參考資料

一、函數式編程

1.1 什么是函數式編程

函數式編程(Functional Programming)是一種編程范式,它將計算視為數學函數的求值,強調使用純函數和不可變數據。

除了函數式編程之外, 還有 命令式編程,聲明式編程 等編程范式。

在函數式編程中,函數是一等公民,它可以作為參數傳遞給其他函數,也可以作為返回值返回。函數式編程避免了副作用(Side Effects)和共享狀態,這樣可以提高代碼的可維護性、可測試性和并發性。

1.2 函數式編程特征

以下是函數式編程的一些主要特征:

  1. 純函數(Pure Functions): 函數的輸出只依賴于輸入,不依賴于任何外部狀態或可變數據。相同的輸入始終產生相同的輸出,而且沒有副作用。
  2. 不可變數據(Immutable Data): 數據一旦被創建就不能被更改。如果需要修改數據,通常會創建一個新的數據副本。
  3. 函數是一等公民(First-Class Functions): 函數跟其它的數據類型一樣處于平等地位,可以被當作參數傳遞給其他函數,也可以被作為返回值返回。
  4. 高階函數(Higher-Order Functions): 函數可以接受一個或多個函數作為參數,并且可以返回一個函數。
  5. 遞歸(Recursion): 在函數式編程中,遞歸是一種常見的控制結構,因為循環通常依賴于可變狀態,而函數式編程強調不可變性。
  6. Lambda 表達式: Lambda 表達式是一種匿名函數,它允許在代碼中直接定義簡短的函數。
  7. 惰性求值(Lazy Evaluation): 只在需要時計算表達式的值,而不是在每個可能的地方都計算。
  8. 模塊化和組合性(Modularity and Compositionality): 將問題分解為小的、可復用的函數,通過組合這些函數來構建更復雜的功能。

函數式編程最重要的特征是 純函數函數是一等公民

函數式編程不是一個特定語言的概念,而是一種編程風格或哲學。雖然一些編程語言(如Haskell、Scala、Clojure)更天然地支持函數式編程,但在越來越多的編程語言中,如Java、JavaScript、Python,也引入了函數式編程的特性。函數式編程的思想對于處理并發、提高代碼可維護性和表達力都有很大的幫助。

1.2.1 純函數

純函數是指相同的輸入總會得到相同的輸出,并且不會產生副作用的函數。純函數的兩個特點:

  • 相同的輸入必有同輸出
  • 無副作用。無副作用 指的是函數內部的操作不會對外部產生影響(如修改全局變量的值等)。

舉個例子,

public class Person{private int a = 1;public int add(int b){return a + b;}public int pow(int c){return c * c;}public static void main(String[] args){Person p = new Person();p.add(1);p.pow(2);}
}

上面代碼中add(int b)這個方法就不符合函數式編程,這個函數調用后的結果不確定,它的結果不僅取決于b還取決于字段a。而pow(int c)這函數就是符合函數式編程的典范,只要調用它,輸入的值c確定了返回值就肯定確定了。

1.2.2 函數是一等公民

在編程語言中,將函數視為一等公民(First-Class Citizen)意味著函數具有以下特性:

  1. 可以賦值給變量: 可以將函數賦值給變量,使得函數可以像其他數據類型一樣在程序中被存儲和傳遞。
  2. 可以作為參數傳遞: 可以將函數作為參數傳遞給其他函數,這使得函數可以參與更高階的操作,如函數的組合和轉換。
  3. 可以作為返回值: 函數可以作為其他函數的返回值,使得函數可以生成和返回其他函數。
  4. 可以存儲在數據結構中: 函數可以存儲在數組、列表、集合等數據結構中,允許對函數進行組織和管理。

在支持函數作為一等公民的編程語言中,函數與其他數據類型(如整數、字符串等)具有相同的地位,可以像操作其他數據一樣靈活地使用。這種特性是函數式編程風格的核心之一。

舉個簡單的例子,假設有一個接受兩個整數和一個函數作為參數的函數 operate

@FunctionalInterface
public interface IntBinaryOperator {int applyAsInt(int left, int right);// 其他默認方法和靜態方法...
}public class FunctionAsFirstClassCitizenExample {// 函數作為參數public static int operate(int a, int b, IntBinaryOperator operator) {return operator.applyAsInt(a, b);}// 函數作為返回值public static IntBinaryOperator getOperator(String operation) {switch (operation) {case "+":return (x, y) -> x + y;case "-":return (x, y) -> x - y;case "*":return (x, y) -> x * y;default:throw new IllegalArgumentException("Unsupported operation: " + operation);}}public static void main(String[] args) {// 函數賦值給變量IntBinaryOperator addition = (x, y) -> x + y;// 函數作為參數傳遞int result = operate(5, 3, addition);System.out.println("Result of addition: " + result);// 函數作為返回值IntBinaryOperator selectedOperator = getOperator("*");// 調用返回的函數int result2 = operate(4, 2, selectedOperator);System.out.println("Result of multiplication: " + result2);}}

在這個例子中,IntBinaryOperator 是 Java 中的一個函數式接口,用于表示接受兩個整數參數并返回一個整數結果的操作。它定義了一個抽象方法 applyAsInt(int left, int right),用于執行具體的整數操作。函數 operate 接受兩個整數和一個函數作為參數,函數 getOperator 返回一個函數。。這展示了函數作為一等公民的特性,可以方便地傳遞和組合。

1.3 函數式編程在java中的實踐

Java 8 引入了對函數式編程的支持,主要通過以下幾個特性來實現:

  1. Lambda 表達式: Lambda 表達式是 Java 8 中引入的一個重要特性,它使得能夠以更為簡潔的方式表示匿名函數。Lambda 表達式可以用來實現函數式接口(只包含一個抽象方法的接口)。

    javaCopy code// 舊的方式使用匿名內部類
    Runnable runnable1 = new Runnable() {@Overridepublic void run() {System.out.println("Hello, World!");}
    };// 使用 Lambda 表達式
    Runnable runnable2 = () -> System.out.println("Hello, World!");
    
  2. 函數式接口: 函數式接口是一個只包含一個抽象方法的接口。Java 8 引入了 @FunctionalInterface 注解來標識函數式接口,以便編譯器檢查。常見的函數式接口包括 RunnableCallableComparator 等。

    javaCopy code@FunctionalInterface
    interface MyFunction {void apply();
    }
    
  3. Stream API: Stream API 提供了一種對集合進行聲明式操作的方式,支持函數式編程風格的數據處理。它允許對集合進行過濾、映射、歸約等操作,而不需要顯式使用循環。

    javaCopy codeList<String> words = Arrays.asList("apple", "banana", "orange");// 使用 Stream 進行操作
    long count = words.stream().filter(word -> word.length() > 5).count();
    
  4. 默認方法和靜態方法: 接口中引入的默認方法和靜態方法使得在接口中引入新方法變得更為靈活。這對于在函數式編程中向接口添加新功能非常有用,而不會破壞現有實現。

    javaCopy codeinterface MyInterface {default void defaultMethod() {System.out.println("Default method");}static void staticMethod() {System.out.println("Static method");}void abstractMethod();
    }
    
  5. Optional 類: Optional 類是 Java 8 引入的一個用于處理可能為 null 的值的容器類。它通過一系列的函數式方法來支持更安全、更函數式的處理空值的方式。

    javaCopy codeOptional<String> name = Optional.ofNullable(getName());
    String result = name.orElse("Unknown");
    

這些特性使得 Java 在某種程度上支持函數式編程范式,盡管 Java 仍然是一門面向對象編程的語言。除了以上特性,一些第三方庫,如Guava和Vavr,提供了更多函數式編程支持的工具和數據類型。在 Java 9、Java 10 和 Java 11 中,也進一步增強了函數式編程的支持,例如引入了模塊化系統和新的集合操作方法。

參考資料

什么是「函數式編程」? - 知乎 (zhihu.com)

詳解Java中的三種函數式編程,以及具體的實現方法 | w3cschool筆記

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

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

相關文章

ES6中的迭代器和set、map集合

什么是迭代器&#xff1f; 一種機制&#xff0c;也是一種接口&#xff0c;為數據結構提供統一訪問接口&#xff0c;依次處理數據據結構成員 只要實現了迭代器接口&#xff0c;就可以使用for...of循環遍歷。 /*** 迭代器是一種機制 是一種接口 只要數據解構實現了接口 就可…

力扣labuladong一刷day36天

力扣labuladong一刷day36天 一、96. 不同的二叉搜索樹 題目鏈接&#xff1a;https://leetcode.cn/problems/unique-binary-search-trees/ 思路&#xff1a;這是一道典型的動態規劃題&#xff0c;從n3來看 子樹有幾種形態 (0, 2)、(1, 1)、(2, 0)有規律可循&#xff0c;即為左…

飛天使-linux操作的一些技巧與知識點4

文章目錄 ansible配置文件的優先級嘗試開始進行操作ansible常用模塊ansible 的playbook示例安裝phpplaybook中變量的引用 ansible yum install -y ansible 測試是否可用 ansible localhost -m ping /etc/ansible/ansible.cfg &#xff1a;主配置文件&#xff0c;配置 ansible…

大公司求我用Kotlin寫個通用爬蟲模板

bug虐我千百遍&#xff0c;我待他如初戀。每次深夜挑燈都是我與bug較量的時間。今天我要說的就是寫一個爬蟲模版&#xff0c;自動抓取百度圖片的教程&#xff0c;這次使用Kotlin編寫的爬蟲程序在Scrapy框架下完成的&#xff0c;如有不足歡迎指正。 首先&#xff0c;使用Kotlin編…

Mybatis-Plus源碼解析之@MapperScan(一)

group : com.baomidou version:3.5.2.2-SNAPSHOT baomidou官網可以從快速開始了解到&#xff0c;除了配置數據源&#xff0c;最重要的就是MapperScan 注解&#xff0c;在 Spring Boot 啟動類中添加 MapperScan 注解&#xff0c;掃描 Mapper 文件夾。 MapperScan 按照慣例&…

angular form 組件、雙向綁定;反應式表單

1.使用雙向綁定&#xff0c;以及angular的表單提交功能 app.moudle中引入 雙向綁定 [(ngModel)]"text" ??????? 效果 提交表單 2.反應式表單 在app.module.ts中引入在組件中引入&#xff0c;并放在一個變量里 在初始化時實列化這個module 定義規則 在html…

Linux:環境變量

目錄 1.基本變量 2.通過代碼獲取環境變量 2.1 main傳參 2.2 全局變量environ 2.3 系統調用getenv() 3.在腳本文件中添加環境變量 4.環境變量通常是具有全局屬性 1.基本變量 環境變量(environment variables)一般是指在操作系統中用來指定操作系統運行環境的一些參數…

商用中央空調市場分析:預計2028年將達到628億元

商用空調一直以來都沒有一個相對比較明確的概念&#xff0c;一直以來被認為是制冷空調市場的一個細分子行業。現在比較一致的觀點是&#xff0c;可以納入商用空調范疇的產品可以包括戶式中央空調產品、部分傳統中央空調產品以及部分家用空調。商用空調已普遍采用直流變頻領先技…

網絡計算機模擬實現

今天給大家說說前幾天完成的一個模擬的網絡計算機吧&#xff0c;雖然計算機的模擬實現的原理很簡單&#xff0c;但是如果要想寫乘網絡的&#xff0c;個人認為是不簡單的。基本上算是包涵了套接字編程的三分之一的知識點&#xff0c;此處的套接字編程指的是在理解TCP/IP五層協議…

泡沫玻璃市場分析:預計2028年將達到14億美元

泡沫玻璃最早是由美國匹茲堡康寧公司發明的&#xff0c;是由碎玻璃、發泡劑、改性添加劑和發泡促進劑等&#xff0c;經過細粉碎和均勻混合后&#xff0c;再經過高溫熔化&#xff0c;發泡、退火而制成的無機非金屬玻璃材料。它是由大量直徑為1~2毫米的均勻氣泡結構組成。其中吸聲…

Linux 常用命令----mktemp 命令

文章目錄 基本用法實例演示高級用法注意事項 mktemp 命令用于創建一個臨時文件或目錄&#xff0c;這在需要處理臨時數據或進行安全性測試時非常有用。使用 mktemp 可以保證文件名的唯一性&#xff0c;避免因文件名沖突而導致的問題。 基本用法 創建臨時文件: 命令 mktemp 默認…

Go語言基礎知識學習(一)

Go基本數據類型 bool bool型值可以為true或者false,例子&#xff1a; var b bool true數值型 類型表示范圍int8有符號8位整型-128 ~ 127int16有符號16位整型-32768 ~ 32767int32有符號32位整型-2147783648 ~ 2147483647int64有符號64位整型uint8無符號8位整型0 ~ 255uint16…

優思學院|如何建立公司運營指標體系?如何推行六西格瑪改進運營指標?

關鍵績效指標 (KPI) 是測量您團隊或組織朝重要商業目標進展表現如何的量化指標&#xff0c;組織會在多個層面使用 KPI&#xff0c;這視乎您想要追蹤何指標而定&#xff0c;您可以設定全組織的、特定團隊的、或甚至是個人 KPI。 良好的KPI能讓公司管理者掌握組織的營運是否進度…

使用React 18、Echarts和MUI實現溫度計

關鍵詞 React 18 Echarts和MUI 前言 在本文中&#xff0c;我們將結合使用React 18、Echarts和MUI&#xff08;Material-UI&#xff09;庫&#xff0c;展示如何實現一個交互性的溫度計。我們將使用Echarts繪制溫度計的外觀&#xff0c;并使用MUI創建一個漂亮的用戶界面。 本文…

點評項目——分布式鎖

2023.12.10 集群模式下的并發安全問題及解決 隨著現在分布式系統越來越普及&#xff0c;一個應用往往會部署在多臺機器上&#xff08;多節點&#xff09;&#xff0c;通過加鎖可以解決在單機情況下的一人一單安全問題&#xff0c;但是在集群模式下就不行了。見下圖&#xff1a…

在 Android WebView 中實現和 JavaScript 的互操作

前言 在 APP 中內嵌一個 H5 來實現特定的業務功能已經是非常成熟且常用的方案了。 雖然 H5 已經能夠實現大多數的需求&#xff0c;但是對于某些需求還是得依靠原生代碼來實現然后與 JavaScript 進行交互&#xff0c;例如我目前所負責的項目就是一個 “智能硬件” 設備&#x…

【PyTorch】卷積神經網絡

文章目錄 1. 理論介紹1.1. 從全連接層到卷積層1.1.1. 背景1.1.2. 從全連接層推導出卷積層 1.2. 卷積層1.2.1. 圖像卷積1.2.2. 填充和步幅1.2.3. 多通道 1.3. 池化層&#xff08;又稱匯聚層&#xff09;1.3.1. 背景1.3.2. 池化運算1.3.3. 填充和步幅1.3.4. 多通道 1.4. 卷積神經…

實現React18加TS,解決通用后臺管理系統,實戰方案落地有效實踐經驗

隨著前端技術的不斷發展和更新&#xff0c;使用React 18結合TypeScript&#xff08;TS&#xff09;來構建通用后臺管理系統已成為一種常見的選擇。本文將介紹如何在項目中應用React 18和TS&#xff0c;并分享一些實戰方案的有效實踐經驗。 一、搭建React 18 TS項目 首先&…

12.2每日一題(1無窮型冪指函數:二倍角公式+三部曲+等價無窮小代換(只有整體的因子不為0才能先算出來))

注意&#xff1a;求極限不能想先算哪里就先算哪里&#xff0c;只有整體的因子不為0才能先算出來&#xff0c;部分不為0不可以先算

外貿老業務也棘手的一個問題

這幾天有2個老業務都被一個類同的問題纏住了。 客戶定購了三臺車&#xff0c;由于是非常規要求所以我建議收取全款或者最少收50%的定金。但是業務員為了當月業績或者為了拿到就收了客戶20% 或者30% &#xff0c;定金收到了&#xff0c;我也不好再逼著業務員去加收定金。 訂單就…