Lambda01 編程範式、lambda表達式與匿名內部類、lambda表達式的寫法
1 編程範式
主要的編程範式有三種:命令式編程,聲明式編程和函數式編程。
1.1 命令式編程
關註計算機執行的步驟,就是告訴計算機先做什麽後做什麽
1.2 聲明式編程
表達程序的執行邏輯,就是告訴計算機要做什麽,不指定具體怎麽做
1.3 函數式編程
跟聲明式編程類似,就是告訴計算機做什麽,不指定具體怎麽做
參考博文
1.4 demo實例
1.4.1 需求
隨機產生一個int類型的數組,分別利用命令式編程和函數值編程獲取數組中的最小值
1.4.2 思路
命令式編程:
隨記產生int類型數組 -> 定義一個int類型變量minNumber並取int的最大值 -> 利用循環遍歷數組 -> 將數組中的每個元素和minNumber進行比較,如果比minNumber小就復制給minNumber,否則就進行下一次循環
函數值編程:
隨記產生int類型數組 -> 定義一個int類型的變量minNumber並取int的最大值 -> 將數組轉化成流 -> 調用的流的相關方法獲取流中的最小值 -> 將獲取到的最小值進行類型轉化後在復制給minNumber
1.4.3 代碼實現
package a_test_demo; import org.junit.Before; import org.junit.Test; import java.util.Arrays; import java.util.Random; import java.util.stream.IntStream;View Code/** * @author 王楊帥 * @create 2018-06-24 17:14 * @desc **/ public class Case02 { /** * 需求:隨機產生一個int類型的數組並通過命令式編程和函數式編程分別求出數組中的最小值 */ private int[] nums; // 定義一個int類型的數組 int count = 10; // 數組長度 Random random; // 隨機數對象 @Before public void init() { random = new Random(); //實例化Random nums = new int[count]; // 實例化數組 for (int i = 0; i < nums.length; i++) { // 修改數組內容 nums[i] = random.nextInt(30); } // System.out.println(Arrays.toString(nums)); // 打印數組信息【測試用】 } /** * 利用命令式編程實現 */ @Test public void test01() { int minNumber = Integer.MAX_VALUE; // 存儲最小值【初始化時時最大值】 for (int i = 0; i < nums.length; i++) { if (minNumber > nums[i]) { minNumber = nums[i]; } } System.out.println(Arrays.toString(nums) + " 中的最小值為: " + minNumber); } /** * 利用函數式編程實現 */ @Test public void test02() { int minNumber = Integer.MAX_VALUE; minNumber = IntStream .of(nums) // 將數組轉化成流 .parallel() // 設置並行處理【PS: 如果是命令式編程需要自己實現相應邏輯】 .min() // 獲取流中的最小值 .getAsInt(); // 將值轉化成int類型 System.out.println(Arrays.toString(nums) + " 中的最小值為: " + minNumber); } }
2 lambda表達式與匿名內部類
2.1 需求
現有一個名為getName的方法,該方法的參數是一個Student接口;怎麽調用getName方法
2.2 思路
2.2.1 思路一
創建一個名為StudentImpl的類,該類實現了Student接口 -> 調用getName方法時傳入StudentImpl的實例即可
2.2.2 思路二
利用匿名內部類作為getName方法的實參
2.2.3 思路三
利用lambda表達式作為getName方法的實參
2.3 代碼實現
package a_test_demo; import org.junit.Test; public class Case01 { /** * getName方法:用戶打印學生的姓名 * @param student Student接口 */ public void getName(Student student) { System.out.println("學生的姓名為:" + student.name()); } /** * 利用實現類實現 */ @Test public void test01() { Student student = new StudentImpl(); getName(student); } /** * 利用匿名內部類實現 */ @Test public void test02() { getName(new Student() { @Override public String name() { return "fury"; } }); } /** * 利用lambda表達式實現 */ @Test public void test03() { getName(() -> "zeus"); } } /** * Student接口 */ interface Student { /** * 抽象方法:返回String類型的姓名 * @return */ String name(); } /** * Student接口的實現類 */ class StudentImpl implements Student { @Override public String name() { return "warrior"; } }View Code
2.4 三種方法使用場景
2.4.1 實現類
當某個類需要實例化多次時使用
2.4.2 匿名內部類
某個類只需要實例化一次而且不需要知道實例名稱時使用【通常這個類需要進行重寫的方法不止一個】;如果需要知道實例名稱時就需要使用內部類
2.4.3 lambda表達式
某個類需要實例化一次而且不需要知道實例名字【這個類中通常有且只有一個需要重寫的方法】
2.5 為什麽Lambda表達式可以作為方法的參數呢
Lambda 可以作為方法的參數。Lambda 表達式是函數式接口實現類的實例,所以,Lambda 表達式作為方法的參數,實際就是把一個類實例作為方法的參數。Lambda 表達式表達或是設計了一組功能,把它傳遞給方法作為參數,實際上,可以理解為把一組功能傳遞給了方法。因此,為了讓代碼更加簡潔,編程更加高效,調用方法(該方法的參數類型是接口類型)時,若接口有多個抽象方法,我們可以創建這個接口的匿名實現類的實例,作為方法的參數。若是接口只有唯一一個抽象方法,比如函數式接口,我們可以創建這個接口的 Lambda 表達式,作為調用方法的參數,把一組功能傳遞給方法。
技巧01:lambda表達式 “->” 左邊相當於函數式接口中那個方法的形參,“->” 的右邊相當於函數式接口中那個方法的返回值
技巧02:函數式接口就是只有一個抽象方法的接口
3 lambda表達式的寫法
Lambda01 編程範式、lambda表達式與匿名內部類、lambda表達式的寫法