0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

JDK中常見的Lamada表達式

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-10 15:07 ? 次閱讀

JDK中有許多函數(shù)式接口,也會有許多方法會使用函數(shù)式接口作為參數(shù),同時在各種源碼中也大量使用了這些方法,那么我們在實際工作中應該如何使用!我們就來盤一盤,這樣也有助于寫出優(yōu)雅的代碼,使我們在閱讀源碼時事半功倍。

1 JDK中常見的Lamada表達式

Java中可以使用Lamada表達式的接口都有@FunctionalInterface注解。

先來看看util.function包下面含有FunctionalInterface注解的接口。一屏顯示不全,可見功能非常齊全。

鑒于常用的一些函數(shù)式接口有Function/Consumer/Supplier/Predicate以及Runnable等。本篇介紹這幾類接口。

圖片

圖片

1.1 Runnable

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

Runnable 使用Lamada方式書寫時,無參數(shù),無返回值。最終執(zhí)行的是run方法

使用Demo

new Thread(() - > {
    System.out.println("JavaNorth Runnable");
}).start();

1.2 Function

Function 表示接受一個參數(shù)并產(chǎn)生結果的函數(shù)。

@FunctionalInterface
public interface Function< T, R > {
    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

    default < V > Function< V, R > compose(Function< ? super V, ? extends T > before) {
        Objects.requireNonNull(before);
        return (V v) - > apply(before.apply(v));
    }
    default < V > Function< T, V > andThen(Function< ? super R, ? extends V > after) {
        Objects.requireNonNull(after);
        return (T t) - > after.apply(apply(t));
    }

    static < T > Function< T, T > identity() {
        return t - > t;
    }
}

Function接受一個參數(shù)T,并且有返回值 R, 其實現(xiàn)也主要是實現(xiàn)此方法 R apply(T t);

Function 的一個示例:

List< String > list = new ArrayList< String >();
List< String > collect = list.stream().map((x) - > {
    return "Java North Function" + x;
}).collect(Collectors.toList());

上述示例中是一個stream的map方法。其中x為輸入?yún)?shù),『"Java North and" + x』為輸出。

1.3 Consumer

Consumer表示接受一個參數(shù),沒有返回值的操作,主要方法為 void accept(T t);

@FunctionalInterface
public interface Consumer< T > {
    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    default Consumer< T > andThen(Consumer< ? super T > after) {
        Objects.requireNonNull(after);
        return (T t) - > { accept(t); after.accept(t); };
    }
}
1.3.1 Consumer 在Java中的應用

常見的有List的forEach等。

list.forEach(x - > System.out.println( "Java North Consumer test " + x));

x為參數(shù),輸出語句直接執(zhí)行。

下面的map的forEach參數(shù)為BiConsumer,其入?yún)⒂袃蓚€。

Map String,String > map = new HashMap  >();
map.forEach((K,V) - > {
    System.out.println("Java North Big Consumer MAP key : " +K + " value: "+V );
});
1.3.2 自定義帶有Consumer的方法
public class ConsumerBiConsumerDemo {
    public static void main(String[] args) {
        Consumer< String > conString = (x) - > System.out.println(x.toUpperCase());
        conString.accept("i love java north ");

        BiConsumer< String, String > biCon = (x,y) - > System.out.println (x + y);
        biCon.accept("i love ","java");

        List< Person > plist = Arrays.asList(new Person("Java"),new Person("North"));
        acceptAllEmployee(plist,p - > System.out.println(p.name));
        acceptAllEmployee(plist,person - > {person.name = "unknow";});
        acceptAllEmployee(plist,person - > System.out.println(person.name));
    }

    public static void acceptAllEmployee(List< Person > plist, Consumer< Person > con){
        plist.forEach(person - > {con.accept(person);});
    }
}
class Person{
    public String name;
    public Person (String name){
        this.name = name;
    }
}

1.4 Supplier

Supplier沒有參數(shù),有一個返回值。

@FunctionalInterface
public interface Supplier< T > {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

Supplier 示例如下:

public class SupplierDemo {

    public static void main(String[] args) {
        SupplierDemo sdemo = new SupplierDemo();
        Supplier< LocalDateTime > s = () - > LocalDateTime.now();
        LocalDateTime localDateTime = s.get();
        System.out.println(s.get());

        Supplier< List > listSupplier = sdemo.listSupplier();
        List list = listSupplier.get();

        Person person = personFactory(Person::new);
        System.out.println(person);

        Person javaNorth = personFactory(() - > new Person("JavaNorth"));
        System.out.println(javaNorth);
    }

    public Supplier< List > listSupplier(){
        return ArrayList::new;
    }


    public static Person personFactory(Supplier< ? extends Person > s){
        Person person = s.get();
        if(person.getName() == null)  person.setName("default");
        person.setAge(18);
        return person;
    }


    static class Person {
        String name;
        int age;
        public Person() {   }
        public Person(String name) {
            this.name = name;
        }
       。。。
    }
}

1.5 Predicate

主要方法為test,其主要是傳入一個參數(shù),返回一個boolean類型的值。

@FunctionalInterface
public interface Predicate< T > {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

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

    default Predicate< T > negate() {
        return (t) - > !test(t);
    }

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

Predicate簡單示例:

public class PredicateDemo {
    public static void main(String[] args) {
        Predicate< Integer > predicate = (s) - > s > 5;
        Predicate< Integer > predicate2 = (s) - > s > 8;
        System.out.println(" 3 大于5 ? " + predicate.test(3));
        System.out.println(" 6 大于5 ? " + predicate.test(6));

        System.out.println("7 大于5 and 大于8 " + predicate.and(predicate2).test(7));
        System.out.println("7 大于5 or 大于8 " + predicate.or(predicate2).test(7));

        List< Integer > list = Arrays.asList(3,5,6,2,8,4,7,9);
        List< Integer > collect = list.stream().filter(predicate).collect(Collectors.toList());

        System.out.println(list);
        System.out.println(collect);
    }
}

上述代碼運行結果

3 大于5 ? false
 6 大于5 ? true
7 大于5 and 大于8 false
7 大于5 or 大于8 true
[3, 5, 6, 2, 8, 4, 7, 9]
[6, 8, 7, 9]

2 常用的Lamada參數(shù)特征

Lamada 的一些表達式將方法的一些執(zhí)行邏輯放到了參數(shù)中,使得方法的返回值根據(jù)傳入的參數(shù)的邏輯而變化。從而實現(xiàn)了在一定的方法不變的情況下,使代碼執(zhí)行傳入?yún)?shù)相關的邏輯。

常用的一些Lamada使用如下:

Runnable 無入?yún)?,無返回值 。

() - > { System.out.println(strF.apply("javaNorth Runnable"));}

Function 有入?yún)?,有返回?/strong>

Function strF = (s) - > { return s + "javaNorth Function"; };
System.out.println(strF.apply("TEST "));

Consumer有入?yún)?,無返回值。

Consumer< String > srtC = (s) - > {System.out.println(s + "javaNorth TEST ");};
srtC.accept("Hello World");

Supplier 無入?yún)ⅲ蟹祷刂怠?/strong>

Supplier< String > srtP = () - > {return "I love avaNorth ";};
System.out.println(srtP.get());

Predicate 有入?yún)?,返回一個boolean類型的值

Predicate< Integer > predicate = (s) - > s > 5;
System.out.println(" 3 大于5 ? " + predicate.test(3));

3 自定義Lamada函數(shù)式接口

結合之前的常用Lamada函數(shù)的介紹,下面我們自定義一個簡單的函數(shù)式接口。

@FunctionalInterface
public interface MyFunction< T > {
   public void print(T t);
}

public class MyFunctionDemo {
    public static void printString(String str , MyFunction< String > myF){
        myF.print(str);
    }
    public static void main(String[] args) {
        printString("I love " , (str) - > {System.out.println(str + "Java North");});
    }
}

其實很簡單,就是展示了一下自定義函數(shù)式接口的應用實例而已。

總結

函數(shù)式接口的使用可以簡化我們的代碼,很大程度上提高代碼的可讀性。在程序執(zhí)行上可能性能稍微有所降低,但對開發(fā)帶來的便捷與好處是大于其性能上的微弱損失的。除了介紹的幾種常見的函數(shù)式編程以外,還有許多其他的函數(shù)式接口等著我們?nèi)ダ?。聽完這些話之后,軟軟猿妹也對常用的函數(shù)式接口有所了解,接下來下定決心要好好學一學函數(shù)式接口了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8254

    瀏覽量

    149942
  • 函數(shù)
    +關注

    關注

    3

    文章

    4235

    瀏覽量

    61965
  • JDK
    JDK
    +關注

    關注

    0

    文章

    80

    瀏覽量

    16548
收藏 人收藏

    評論

    相關推薦

    什么是正則表達式?正則表達式如何工作?哪些語法規(guī)則適用正則表達式?

    正則表達式又稱規(guī)則表達式(Regular Expression,在代碼中常簡寫為 regex、regexp 或 RE),是一種用于匹配、查找、替換文本的強大工具。它能夠以特定的模式匹配字符串,從而
    的頭像 發(fā)表于 11-03 14:41 ?1746次閱讀
    什么是正則<b class='flag-5'>表達式</b>?正則<b class='flag-5'>表達式</b>如何工作?哪些語法規(guī)則適用正則<b class='flag-5'>表達式</b>?

    如何創(chuàng)建正則的表達式?

    正則表達式:用于匹配規(guī)律規(guī)則的表達式,正則表達式最初是科學家對人類神經(jīng)系統(tǒng)的工作原理的早期研究,現(xiàn)在在編程語言中有廣泛的應用,經(jīng)常用于表單校驗,高級搜索等。
    發(fā)表于 10-27 15:49

    防范表達式的失控

    在C 語言中,表達式是最重要的組成部分之一,幾乎所有的代碼都由表達式構成。表達式的使用如此廣泛,讀者也許會產(chǎn)生這樣的疑問,像+ 、- 、3 、/ 、& & 這樣簡單的運算也會出現(xiàn)
    發(fā)表于 04-22 16:57 ?13次下載

    深入淺出boost正則表達式

    什么是正則表達式?正則表達式是一種用來描述一定數(shù)量文本的模式。Regex代表Regular Express. 如果您不知道什么是正則表達式,請看這篇文章:深入淺出之正則表達式
    發(fā)表于 09-08 18:09 ?9次下載

    Python正則表達式的學習指南

    本文介紹了Python對于正則表達式的支持,包括正則表達式基礎以及Python正則表達式標準庫的完整介紹及使用示例。本文的內(nèi)容不包括如何編寫高效的正則表達式、如何優(yōu)化正則
    發(fā)表于 09-15 08:00 ?0次下載
    Python正則<b class='flag-5'>表達式</b>的學習指南

    Python正則表達式指南

    本文介紹了Python對于正則表達式的支持,包括正則表達式基礎以及Python正則表達式標準庫的完整介紹及使用示例。本文的內(nèi)容不包括如何編寫高效的正則表達式、如何優(yōu)化正則
    發(fā)表于 03-26 09:13 ?10次下載
    Python正則<b class='flag-5'>表達式</b>指南

    Oracle中常用的函數(shù)與表達式講解

    Oracle中常用的函數(shù)與表達式講解(ups電源技術支持工程師招聘)-該文檔為Oracle中常用的函數(shù)與表達式講解文檔,是一份還算不錯的參考文檔,感興趣的可以看看,,,,,,,,,,,
    發(fā)表于 09-28 12:56 ?2次下載
    Oracle<b class='flag-5'>中常</b>用的函數(shù)與<b class='flag-5'>表達式</b>講解

    Lambda表達式詳解

    C++11中的Lambda表達式用于 **定義并創(chuàng)建匿名的函數(shù)對象** ,以簡化編程工作。下面看一下Lambda表達式的基本構成。
    的頭像 發(fā)表于 02-09 11:28 ?1028次閱讀

    表達式與邏輯門之間的關系

    邏輯表達式是指表示一個表示邏輯運算關系的式子,是一個抽象的類似數(shù)學表達式,下面我們重點說明下其表達式與邏輯門之間的關系。
    的頭像 發(fā)表于 02-15 14:54 ?1413次閱讀
    <b class='flag-5'>表達式</b>與邏輯門之間的關系

    C語言的表達式

    在C語言中,表達式是由操作符和操作數(shù)組成。表達式可以由一個或者多個操作數(shù)組成,不同的操作符與操作數(shù)組成不同的表達式,因此,表達式才是C語言的基本。
    的頭像 發(fā)表于 02-21 15:09 ?1168次閱讀
    C語言的<b class='flag-5'>表達式</b>

    shell腳本基礎:正則表達式grep

    在Linux上有許多命令可以使用正則表達式,其中最常見的是grep命令和sed命令。正則表達式有多種類型,每種類型中可以使用的元字符類型不同。最常見的是基本正則
    的頭像 發(fā)表于 05-29 09:29 ?1054次閱讀
    shell腳本基礎:正則<b class='flag-5'>表達式</b>grep

    一文詳解Verilog表達式

    表達式由操作符和操作數(shù)構成,其目的是根據(jù)操作符的意義得到一個計算結果。表達式可以在出現(xiàn)數(shù)值的任何地方使用。
    的頭像 發(fā)表于 05-29 16:23 ?2552次閱讀
    一文詳解Verilog<b class='flag-5'>表達式</b>

    如何使用lambda表達式提升開發(fā)效率?

    Java8 的一個大亮點是引入 Lambda 表達式,使用它設計的代碼會更加簡潔。當開發(fā)者在編寫 Lambda 表達式時,也會隨之被編譯成一個函數(shù)式接口。
    發(fā)表于 08-24 10:25 ?240次閱讀

    zabbix觸發(fā)器表達式 基本RS觸發(fā)器表達式 rs觸發(fā)器的邏輯表達式

    zabbix觸發(fā)器表達式 基本RS觸發(fā)器表達式 rs觸發(fā)器的邏輯表達式? Zabbix是一款開源的監(jiān)控軟件,它能通過監(jiān)控指標來實時監(jiān)測服務器和網(wǎng)絡的運行狀態(tài),同時還能提供警報和報告等功能來幫助管理員
    的頭像 發(fā)表于 08-24 15:50 ?1435次閱讀

    linux正則表達式匹配字符串

    在Linux操作系統(tǒng)中,正則表達式是一種強大的模式匹配工具,它可以用于在文本中查找、替換和篩選特定的字符串。準確掌握正則表達式的語法和常見應用,對于Linux系統(tǒng)的管理員和開發(fā)人員來說
    的頭像 發(fā)表于 11-23 10:26 ?570次閱讀