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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】函数式编程

發布時間:2024/7/5 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】函数式编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 函數式接口

1.1 概念

函數式接口是有且僅有一個抽象方法的接口,可以包括靜態和默認方法。

@FunctionalInterface:加上注解,檢測是否的函數式接口

@FunctionalInterface public interface MyFunctionInterface {public abstract void method();static void method2() {}default void method3() {} }

1.2 函數式接口的使用

一般可以作為方法的參數返回值類型

public static void show(MyFunctionInterface myInter){myInter.method();}public static void main(String[] args) {show(new MyFunctionInterface() {@Overridepublic void method() {System.out.println("使用匿名內部類重寫接口中的抽象方法");}});show(()->{System.out.println("使用lambda表達式重寫接口的抽象方法");});show(()-> System.out.println("使用簡化lambda表達式重寫接口的抽象方法"));}

2 函數式編程

2.1 性能浪費案例

public static void showLog(int level, String message){if(level==1){System.out.println(message);}}public static void main(String[] args) {String msg1 = "Hello";String msg2 = "Hello";String msg3 = "Hello";showLog(1,msg1+msg2+msg3);}

調用showLog方法,第二個參數式拼接后的字符串,如果等級不是1,message不需要輸出,存在浪費。

2.2 Lambda優化案例

@FunctionalInterface public interface MessageBuider {String buiderMessage(); } public static void showLog(int level, MessageBuider mb){if(level==1){System.out.println(mb.buiderMessage());;}}public static void main(String[] args) {String m1 = "Hello";String m2 = "Zhangsan";showLog(1, ()->{return m1+m2;});}

這里只有滿足條件才會調用接口的方法進行字符串拼接。如果不滿足就不會進行字符串拼接,沒有了性能的浪費。

2.3 使用Lambda作為參數和返回值

作為參數

//Runnable是一個函數式接口public static void startThread(Runnable run){new Thread(run).start();}public static void main(String[] args) {startThread(()->System.out.println("開啟線程"+Thread.currentThread().getName()));}

作為返回值

//Comparator是一個函數式接口public static Comparator<String> getComparator(){return (o1, o2) -> o2.length()-o1.length();}public static void main(String[] args) {String[] arr = {"aaa","bbbbb","cccccc"};Arrays.sort(arr);System.out.println(Arrays.toString(arr));//[aaa, bbbbb, cccccc]Arrays.sort(arr,getComparator());System.out.println(Arrays.toString(arr));//[cccccc, bbbbb, aaa]}

3 常用的函數式接口

3.1 Supplier接口

僅包含一個無參方法:T get()
用來獲取一個泛型參數指定類型的對象數據。由于這是一個函數式接口,這也就意味著對應的Lambda表達式需要“對外提供”一個符合泛型類型的對象數據。

// Supplier<String>作為參數public static String getString(Supplier<String> sup){return sup.get();}public static void main(String[] args) {String str = getString(()->"哈哈哈");System.out.println(str);}

練習:應用Supplier求數組最大值

public static int getMax(Supplier<Integer> sup){return sup.get();}public static void main(String[] args) {int[] arr = {5,6,2,4,1,7,3};int ans = getMax(() -> {int max = arr[0];for (int i : arr) {if (i > max) {max = i;}}return max;});System.out.println(Arrays.toString(arr));//[5, 6, 2, 4, 1, 7, 3]System.out.println(ans);//7}

3.2 Consumer接口

consumer接口是一個消費型接口,泛型執行什么類型,可以使用accept方法消費什么類型的數據,至于怎么消費,需要自定義。

public static void method(String name, Consumer<String> con){con.accept(name);}public static void main(String[] args) {//消費方式:輸出method("張三", (name)->{System.out.println(name);});//可以替換為method("張三", System.out::println);//消費方式:反轉輸出method("張三",(name)->{System.out.println(new StringBuilder(name).reverse().toString());});}

默認方法andThen:如果一個方法的參數和返回值全都是Consumer 類型,那么就可以實現效果:消費數據的時候,首先做一個操作,然后再做一個操作,實現組合。而這個方法就是Consumer 接口中的default方法andThen

default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t)> { accept(t); after.accept(t); }; }

備注: java.util.Objects 的requireNonNull 靜態方法將會在參數為null時主動拋出
NullPointerException 異常。這省去了重復編寫if語句和拋出空指針異常的麻煩。

public static void method(String name, Consumer<String> con1, Consumer<String> con2){con1.andThen(con2).accept(name);//相當于👇 // con1.accept(name); // con2.accept(name);}public static void main(String[] args) {//消費方式:將字符串轉換為大寫輸出method("HEllo",(t)->{System.out.println(t.toLowerCase());},(t)->{System.out.println(t.toUpperCase());});}

練習andThen:格式化打印信息
下面的字符串數組當中存有多條信息,請按照格式“ 姓名:XX。性別:XX?!钡母袷綄⑿畔⒋蛴〕鰜?。要求將打印姓名的動作作為第一個Consumer 接口的Lambda實例,將打印性別的動作作為第二個Consumer 接口的Lambda實例,將兩個Consumer 接口按照順序“拼接”到一起。

public static void method(String[] arr, Consumer<String> con1, Consumer<String> con2){for(String str: arr){con1.andThen(con2).accept(str);}}public static void main(String[] args) {String[] array = { "張三,男", "李四,男", "王五,女" };method(array,(str)->{String[] split = str.split(",");System.out.print("姓名:"+split[0] + "。");},(str)->{String[] split = str.split(",");System.out.println("性別:"+split[1]+"。");});}

3.3 Predicate接口

作用:對數據類型的數據進行判斷,結果返回boolean值

抽象方法test:用來對指定數據類型的數據進行判斷的方法

public static boolean checkString(String s, Predicate<String> pre){return pre.test(s);}public static void main(String[] args) {String s = "abcd";boolean check = checkString(s, (str) -> str.length() > 5);System.out.println(check);}

默認方法and
既然是條件判斷,就會存在與、或、非三種常見的邏輯關系。其中將兩個Predicate 條件使用“與”邏輯連接起來實現“并且”的效果時,可以使用default方法and 。其JDK源碼為:

default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t)> test(t) && other.test(t); }

定義兩個判斷條件:字符串長度大于5,字符串包含a,條件要同時滿足

public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2){return pre1.and(pre2).test(s);//相當于👇//return pre1.test(s) && pre2.test(s);}public static void main(String[] args) {String s = "abcdef";boolean check = checkString(s, (str) -> str.length() > 5,(str) -> str.contains("a"));System.out.println(check);}

默認方法or
與and 的“與”類似,默認方法or 實現邏輯關系中的“或”。JDK源碼為:

default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t)> test(t) || other.test(t); }

定義兩個判斷條件:字符串長度大于5,字符串包含a,條件滿足一個即可

public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2){return pre1.or(pre2).test(s);//相當于👇 // return pre1.test(s) || pre2.test(s);}public static void main(String[] args) {String s = "a";boolean check = checkString(s, (str) -> str.length() > 5,(str) -> str.contains("a"));System.out.println(check);}

默認方法negate:“非”(取反)默認方法negate 的JDK源代碼為:

default Predicate<T> negate() {return (t)> !test(t); } public static boolean checkString(String s, Predicate<String> pre){return pre.negate().test(s);//相當于👇//return !pre.test(s);}public static void main(String[] args) {String s = "a";boolean check = checkString(s, (str) -> str.length() > 5);System.out.println(check);}

練習:信息集合篩選
數組當中有多條“姓名+性別”的信息如下,請通過Predicate 接口的拼裝將符合要求的字符串篩選到集合ArrayList 中,需要同時滿足兩個條件:

  • 必須為女生;
  • 姓名大于等于3個字。
  • public static ArrayList<String> filterPerson(String[] arr, Predicate<String> pre1, Predicate<String> pre2) {ArrayList<String> list = new ArrayList<>();for (String str : arr) {if (pre1.and(pre2).test(str)) {list.add(str);}}return list;}public static void main(String[] args) {String[] arr = {"張三,男","張三三,女","李四,男","李四四,女","王五,女","王五五,男"};ArrayList<String> list = filterPerson(arr, (str) -> {String[] split = str.split(",");return "女".equals(split[1]);}, (str) -> {String[] split = str.split(",");return split[0].length() >= 3;});for (String s:list) {System.out.println(s);}}

    3.4 Function接口

    java.util.function.Function<T,R> 接口用來根據一個類型的數據得到另一個類型的數據,前者稱為前置條件,后者稱為后置條件。

    使用場景:根據類型T的參數獲取類型R的結果

    抽象方法:apply

    public static void change(String s, Function<String, Integer> fun){Integer in = fun.apply(s);System.out.println(in);}public static void main(String[] args) {String s = "1234";change(s, (str)->{return Integer.parseInt(s);});}

    默認方法:andThen
    把String類型的123轉換為Integer類型,加上10后,再轉為String類型輸出

    public static void change(String s, Function<String, Integer> fun1, Function<Integer, String> fun2){String strout = fun1.andThen(fun2).apply(s);//fun1先調用apply把字符串轉為Integer//fun2再調用apply把Integer轉為字符串System.out.println(strout);}public static void main(String[] args) {String s = "123";change(s, (str)->{return Integer.parseInt(s);},(num)->{return String.valueOf(num+10);});}

    練習:自定義函數模型的拼接
    請使用Function 進行函數模型的拼接,按照順序需要執行的多個函數操作為:

  • 將字符串截取數字年齡部分,得到字符串;
  • 將上一步的字符串轉換成為int類型的數字;
  • 將上一步的int數字累加100,得到結果int數字。
  • //1. 將字符串截取數字年齡部分,得到字符串;//2. 將上一步的字符串轉換成為int類型的數字;//3. 將上一步的int數字累加100,得到結果int數字。public static void change(String s, Function<String, String> fun1,Function<String, Integer> fun2, Function<Integer, Integer> fun3){Integer num = fun1.andThen(fun2).andThen(fun3).apply(s);System.out.println(num);}public static void main(String[] args) {String s1 = "張三:20";change(s1, (str)->{String[] split = s1.split(":");return split[1];},(s2)->{return Integer.parseInt(s2);},(num)->{return num+100;});}

    總結

    以上是生活随笔為你收集整理的【Java】函数式编程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 丁香六月激情 | 日本在线网址 | 中国少妇无码专区 | 我想看毛片 | 久久免费成人 | 成人在线播放av | 成人av在线网 | 久久久久五月天 | 青青草社区 | 国内激情视频 | 日韩在线电影一区 | www.国产精品| 1000部啪啪未满十八勿入 | 欧洲一级片 | 国产suv精品一区二区四 | 免费日本黄色 | 第四色激情 | 国产精品久久久久一区二区三区 | 日韩三级一区二区三区 | 国产精品毛片久久久久久久av | 天天操婷婷 | 久久综合久久鬼色 | 国产一区二区三区四区 | 九色porny丨精品自拍视频 | 久久伊人久久 | 肉色超薄丝袜脚交69xx | 国产一级一级 | 人妻大战黑人白浆狂泄 | 神秘马戏团在线观看免费高清中文 | 特级西西444www大精品视频 | 久久99精品久久久久久琪琪 | 97人妻精品一区二区三区免费 | 少妇人妻一级a毛片 | av在线不卡免费看 | 亚洲视频免费播放 | 久久精品欧美一区二区三区不卡 | 日韩福利社 | 日本色婷婷 | 稀缺呦国内精品呦 | 亚洲视屏 | 亚洲精品理论 | 久久久久蜜桃 | 国产欧美一区二区三区沐欲 | 国产ts变态重口人妖hd | 日本做受 | 日本va欧美va精品发布 | 天堂中文在线观看 | 日本少妇电影 | 在线播放ww| 精品熟女一区 | 色视av| 中文字幕女优 | 超碰青草 | 国产精品成 | 色婷婷综合网 | 中文字幕亚洲乱码熟女一区二区 | 国产不卡高清 | 日本成人在线免费观看 | 最新超碰 | 伊人网视频在线观看 | juliaannxxxxx高清 黄页网站在线播放 | 蜜桃av一区二区 | 337p粉嫩大胆噜噜噜噜69影视 | 欧美xxxx×黑人性爽 | 免费观看高清在线 | 麻豆视频在线观看免费网站黄 | 国产高清在线 | 久久久久久久香蕉 | 欧美激情黑白配 | 五级 黄 色 片 | 美女被c出白浆 | 激情av中文字幕 | 国产99久久九九精品无码 | 经典av在线 | 少妇把腿扒开让我舔18 | 天堂在线中文在线 | 国产18在线 | 日日夜夜狠狠爱 | 少妇精品无码一区二区免费视频 | 一区二区三区小视频 | 网友自拍第一页 | 入禽太深免费视频 | 欧美高清免费 | 国产在线拍揄自揄拍无码 | 久久久亚洲成人 | 青草操 | 特极毛片 | 色哟哟精品观看 | av手机| 最近最经典中文mv字幕 | 日韩伦理一区二区 | 国产亚洲欧美一区二区 | 极品蜜桃臀肥臀-x88av | 插久久| 91爱爱com | 国产又大又硬又粗 | 亚洲成人激情av | 中日韩一级片 | 欧洲成人午夜精品无码区久久 |