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

歡迎訪問 生活随笔!

生活随笔

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

java

Java函数式编程和Lambda表达式

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

文章目錄

    • 什么是函數式編程
    • Lambda表達式
    • @FunctionalInterface函數式接口
    • Lambda表達式的格式
    • 方法引用

什么是函數式編程

相信大家都使用過面向對象的編程語言,面向對象編程是對數據進
行抽象,而函數式編程是對行為進行抽象。函數式編程讓程序員能夠寫出更加容易閱讀的代碼。那什么時候函數式編程呢?

函數式編程是一種編程的方法論,主要是將行為編寫成一個個的函數。

什么是函數?

函數就是對輸入的值進行處理,返回另外的值。

Lambda表達式

在Java 8 中引入的Labmda表達式是函數式編程的一種實現。

什么是Lambda表達式呢?我們舉個例子

下面的代碼如果使用Java 7 的話應該這樣寫:

//sort using java 7private void sortUsingJava7(List<String> names){ Collections.sort(names, new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return s1.compareTo(s2);}});}

代碼里面需要實現一個匿名類,看起來是不是很復雜? 下面我們用java 8 的lambda表達式將其改寫:

//sort using java 8private void sortUsingJava8(List<String> names){Collections.sort(names, (s1, s2) -> s1.compareTo(s2));} }

其中(s1, s2) -> s1.compareTo(s2) 是Comparator的compare方法的實現。

這里我們使用了Lambda表達式替換了Comparator的匿名類。為什么可以這樣做?什么樣的匿名類才能被Lambda表達式替換呢? 這里我們引入一個概念,叫做函數式接口。

Lambda表達式需要一個函數式接口作為其對應類型,而它的方法體就是函數接口的實現。每一個該接口類型的Lambda表達式都會被匹配到該接口的抽象方法。

@FunctionalInterface函數式接口

所謂函數是接口是指包括如下特征的接口:

  • 接口有且僅有一個抽象方法
  • 接口允許定義靜態方法
  • 接口允許定義默認方法
  • 接口允許java.lang.Object中的public方法

我們看一下上面的Comparator的實現:

@FunctionalInterface public interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj);default Comparator<T> reversed() {return Collections.reverseOrder(this);}default Comparator<T> thenComparing(Comparator<? super T> other) {Objects.requireNonNull(other);return (Comparator<T> & Serializable) (c1, c2) -> {int res = compare(c1, c2);return (res != 0) ? res : other.compare(c1, c2);};}default <U> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor,Comparator<? super U> keyComparator){return thenComparing(comparing(keyExtractor, keyComparator));}default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor){return thenComparing(comparing(keyExtractor));}default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {return thenComparing(comparingInt(keyExtractor));}default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {return thenComparing(comparingLong(keyExtractor));}default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {return thenComparing(comparingDouble(keyExtractor));}public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {return Collections.reverseOrder();}@SuppressWarnings("unchecked")public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;}public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {return new Comparators.NullComparator<>(true, comparator);}public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) { ...}public static <T, U> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor,Comparator<? super U> keyComparator){ ...}public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor){ ...}public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) { ...}public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) { ...}public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) { ...} }

我們可以看到Comparator接口里面有static方法,有default方法,有一個來自Object的boolean equals(Object obj);有一個需要實現的抽象方法int compare(T o1, T o2)

default方法是java 8添加的最新的關鍵詞,表示實現這個接口的類如果不自己實現這個方法,那么就用接口自己的吧,其作用主要是向下兼容。

JDK自帶了一些有用的函數式接口:

  • java.lang.Runnable,

  • java.awt.event.ActionListener,

  • java.util.Comparator,

  • java.util.concurrent.Callable

  • java.util.function包下的接口,如Consumer、Predicate、Supplier等

Lambda表達式的格式

一般來說Lambda的表達式是這樣的格式:

parameter -> expression body

查看下面的代碼:

public static void main(String[] args) {Runnable noArguments = () -> System.out.println("Hello World");ActionListener oneArgument = event -> System.out.println("button clicked");Runnable multiStatement = () -> {System.out.print("Hello");System.out.println(" World");};BinaryOperator<Long> add = (x, y) -> x + y;BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;}

上面是我們經常在Lambda中使用的幾種格式。

  • 不包含參數的格式

    Runnable noArguments = () -> System.out.println(“Hello World”);

  • 只包含一個參數,并可以省略括號

    ActionListener oneArgument = event -> System.out.println(“button clicked”);

  • Lambda的主體是一段代碼塊

    Runnable multiStatement = () -> {
    System.out.print(“Hello”);
    System.out.println(" World");
    };

  • 多個參數

    BinaryOperator add = (x, y) -> x + y;

  • 顯式指定參數的類型

    BinaryOperator addExplicit = (Long x, Long y) -> x + y;

所有Lambda 表達式中的參數類型都是由編譯器推斷得出的。如果編譯器無法推斷你的參數類型,則需要手動指定。

方法引用

在第一個例子中我們講到了如下的Lambda表達式:

Collections.sort(names, (s1, s2) -> s1.compareTo(s2));

其中(s1, s2) -> s1.compareTo(s2) 表示的是兩個字符串的比較,調用了String類的compareTo方法。為了更簡潔的表示業務邏輯,可以是用方法引用來替換Lambda表達式。

Collections.sort(names, String::compareTo);

這樣比原來的代碼更短,而且更加簡潔。

有三種方法可以被引用:

  • 靜態方法
  • 實例方法
  • 使用new的構造函數方法如:(TreeSet::new)

更多精彩內容且看:

  • 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

更多教程請參考 flydean的博客

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

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

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