「JAVA8」- 函數式接口看這篇就夠了

2020-09-22 1024BIT

什麼是函數式接口?

就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。

函數式接口可以被隱式轉換為 lambda 表達式。

特點

  1. 只有一個抽象方法。
  2. 可以有多個非抽象方法的接口。

例如自己定義一個接口

public interface MyInter{ boolean test(boolean test); default andThen(){}}

這個就一個函數式接口。

這個接口我們使用的時候就可以轉化成lambda表達式。

JDK 1.8 之前已有的函數式接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

JDK 1.8 新增加的函數接口:

  • java.util.function

java.util.function 它包含了很多類,用來支持 Java的 函數式編程。

但是

對於函數式接口的裡面,我希望不要局限於,java.util.function包裡面的接口。

什麼意思?

就是說我們抓住函數式接口的特點,一個抽象接口,很多個非抽象接口。java.util.function包裡面的接口只是我們眾多實現的一小部分而已。

接下來,我帶領大家,讀下java.util.function幾個接口的源碼,希望大家理解後,其他的一眼就知道怎麼使用,自己重新自定義。

BiConsumer

誤區:當時我開始看源碼的時候,我總在想Consumer消費者,這個單詞的含義,那就是說明這個接口是用來表示消費的。然後一直理解單詞的意思。用單詞的意思來猜想功能記憶。這樣是不對的。

我們要忘記這個單詞意思,而是回歸它的實現,因為過兩天,我可以定義一模一樣的只是換了一個單詞名稱。

@FunctionalInterfacepublic interface BiConsumer<T, U> { void accept(T t, U u);eption if {@code after} is null */ default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) { Objects.requireNonNull(after); return (l, r) -> { accept(l, r); after.accept(l, r); }; }}

BiConsumer這個玩意的抽象方法,有兩個參數T,U然後無返回。

也就是使用的時候,我們是傳了兩個參數進來,然後兩個參數進行一些列操作,andThen就是後面再執行一次其他的accept。


我們這樣理解後,就知道如果我們有需求,傳入兩個參數,不用返回,就可以使用BiConsumer,再次說明請忘記Consumer的英文單詞意思,只不過就是消費兩個參數,不返回,所以才用Consumer一個簡單名稱定義而已。

接下來看使用。

需求,用戶BiConsumer,列印兩個參數的和

public static void main(String[] args) { BiConsumer<Integer,Integer> addConsumer = (x,y)->{ System.out.println(x+y); }; addConsumer.accept(1,3); }

定義兩個輸入參數

(x,y)->

操作內容是列印x+y

System.out.println(x+y);


那我們現在假設一個功能,輸入兩個Integer,判斷是否相等。我們先搜索java.util.function包裡面是否有這種類似的函數接口。


搜索到了,BitFunction。來看它的定義

@FunctionalInterfacepublic interface BiFunction<T, U, R> { R apply(T t, U u); default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t, U u) -> after.apply(apply(t, u)); }}

它有三個參數,輸入T,U執行方法後返回R

注意,別在意BitFunction的名稱,我們記住實現就可以了。

來看使用。

BiFunction<Integer,Integer,Boolean> booleanBiFunction = (x,y) ->x.equals(y);System.out.println(booleanBiFunction.apply(1,1));

看到這裡我相信大家一定理解了,函數式接口就那麼回事情。

最後我們自己來定義一個函數接口。

需求:日期格式化,第一個參數輸入時間Date,第二參數輸入日期格式化,返回格式化的日期String。

@FunctionalInterfacepublic interface DateLambda { String format(Date date,String format);}public static void main(String[] args) { DateLambda dateLambda = (date, format) -> { SimpleDateFormat data = new SimpleDateFormat(format); return data.format(date); }; System.out.println(dateLambda.format(new Date(),&34;)); }

實現完畢

至於java.util.function中的其他方法,大家自己看一眼應該就知道怎麼使用了。


學海無涯苦做舟,唯有總結才能終!


本篇主要表達了如下觀點:

  • 函數式接口只有一個抽象方法,可以有多個非抽象方法。
  • 函數式接口可以轉化成 lambda 表達式
  • 不要管BiConsumer,BiFunction單詞的意思然後去猜想功能,而是知道它的具體實現,進去看了它的抽象方法就能明白怎麼使用了,然後舉一反三。

推薦閱讀



相關焦點

  • java8的函數式編程解析
    其實在java8就已經有java的函數式編程寫法,只是難度較大,大家都習慣了對象式用法,但在其它語言中都有函數式的用法,如js,scala,函數式其實是抽象到極致的思想。其實在Java8出現之前,我們關注的往往是某一類對象應該具有什麼樣的屬性,當然這也是面向對象的核心--對數據進行抽象。但是java8出現以後,這一點開始出現變化,似乎在某種場景下,更加關注某一類共有的行為(這似乎與之前的接口有些類似),這也就是java8提出函數式編程的目的。如圖1-1所示,展示了面向對象編程到面向行為編程的變化。
  • Java8新特性探索之函數式接口
    為了解決上述問題,Java 8 引入了函數式接口,在 java.util.function 包,它包含一組接口,這些接口是 Lambda 表達式和方法引用的目標類型,每個接口只包含一個抽象方法,稱為函數式方法。
  • Java8中lambda表達式的語法,別人都會的,你還不會嗎?「一」
    函數式編程函數式編程是一種編程方式,它將電腦運算視為函數的計算。函數程式語言最重要的基礎是λ演算(lambda calculus),λ演算的函數可以接受函數當作輸入(參數)和輸出(返回值)。 函數式編程是"結構化編程"的一種,主要思想是把運算過程儘量寫成一系列嵌套的函數調用。
  • 你所不知道的Java8新特性:Lambda表達式和函數式接口
    3、有多個參數,一個返回值/** * 多個參數,有返回值 */ public static void test3() { Comparator<Integer> comparator = (x, y) -> { System.out.println("函數式接口
  • Java中的函數式接口
    什麼是函數式接口java中函數式接口中的定義如下:函數式接口(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。一個接口是不是函數式接口與加不加@FunctionalInterface註解無關;如果一個接口符合"函數式接口"定義,那麼加不加該註解都沒有影響,加上該註解能夠更好地讓編譯器進行檢查。如果編寫的不是函數式接口,但是加上了@FunctionalInterface,那麼編譯器會報錯。
  • 面試官:java8中parallelStream提升數倍查詢效率是怎樣實現的
    的parallelStream(並行流),這裡為什麼不用Thread呢,這裡有一個注意點,我們需要獲取所有所有子任務執行完的時間點,在這個時間點之後才能將結果封裝返回,Thread沒有辦法滿足,這裡parallelStream和函數式接口就登場了。
  • 「office篇」office365專業增強訂閱版怎麼安裝?看這篇就夠了!
    軟體介紹微軟在辦公軟體方面,主推訂閱式的Microsoft Office 365,主要是因為Office 365能獲得持續的安全更新和功能更新,而普通版的Office,比如Office 2016、0ffice 2019,只有安全更新,而沒有功能更新。
  • PHP丨PHP基礎知識之PHP基礎入門——函數「理論篇」
    只在函數內部能用,函數外加需使用,需在函數中使用return關鍵字返回。2、全局變量:聲明的函數外部的變量,稱為全局變量。3、函數中,使用變量,默認使用內部局部變量。如果,需在函數中使用全局變量,需要使用global關鍵字,將全局變量引用函數,才能使用。
  • 「屎」一樣的try「」catch代碼,竟然可以這麼幹掉
    在這之前。你需要知道以下幾個概念:行為參數化:是java8提出的,函數式編程的一種思想,通過把代碼包裝為參數傳遞行為,即把代碼邏輯包裝為一個參數,傳到方法裡。Lambda表達式:java8提出:Lambda表達式理解為簡潔的表示可傳遞的匿名函數的一種方式,它沒有名稱,但它有函數體,參數列表,返回類型。可以拋出一個異常類型。包裝代碼邏輯為參數即使用Lambda表達式。
  • 「JAVA8」- 神奇的雙":"號
    這就是我們Java8中的新特性方法引用。我們可以用一對冒號&34;,通過方法的名字來指向一個方法,可以使語言的構造更緊湊簡潔,減少冗餘代碼。疑惑,那Car::new返回的是什麼呢?是Car對象嗎?ToIntFunction<Integer>JAVA8中&34;把函數變成了參數,傳遞到函數裡面但是&34;為什麼把Car::new轉化成了Supplier<Car>,Integer::valueOf轉化成了ToIntFunction<Integer>呢?
  • 函數式編程/lambda表達式入門
    函數式編程/lambda表達式入門本篇主要講解 lambda表達式的入門,涉及為什麼使用函數式編程,以及jdk8提供的函數式接口 和 接口的默認方法 等等1.什麼是命令式編程命令式編程就是我們去告訴程序如何實現
  • Java8特性之接口方法
    然而,直到今日仍有許多軟體開發者對其相關特性不了解,這可能主要是Java基礎教材更新緩慢的原因。為了使大家對與Java8的特性有全面系統的了解,本公眾號將連續幾篇文章介紹Java8中的各個特性。Java8中新增的特性主要有:Lambda 表達式 − Lambda允許把函數作為一個方法的參數(函數作為參數傳遞進方法中。
  • len(x) 擊敗 x.len(),從內置函數看 Python 的設計思想
    這已經不僅是在說 len 更可讀易懂了,而完全是在拔高 len 的地位。這就好比說,分數 ½中的橫線是數學中的一個「內置」表達式,並不需要再實現什麼接口之類的,它自身已經表明了「某數除以某數」的意思。不同類型的數(整數、浮點數、有理數、無理數…)共用同一個操作符,不必為每類數據實現一種求分數的操作。
  • 初中數學「二次函數」最全知識點匯總!
    今天,給大家整理的是初中數學「二次函數」最全知識點匯總,全文共分為8個部分:知識點總結、學習口訣、易錯分析巧、選解析式、動態最值專題、解題技巧、變式13解、題型歸類,基本囊括了初中數學「二次函數」全部的考點、重難點,強烈推薦家長轉給孩子!
  • 2019拔草魔都,看這1篇就夠了!
    金橋國際商業廣場:嗨夠5天!魔都「萬聖節遛娃攻略」來了!上千隻南瓜、驚悚鬼屋、變裝派對... 維璟廣場:足足120000㎡!大虹橋巨型MALL搞事情,撈王,東來順...7.8折秒殺!
  • 換個角度看GAN:另一種損失函數
    選自Medium作者:Phúc Lê機器之心編譯參與:張璽「本質上,GAN 就是另一種損失函數。」Jeremy Howardf 老師曾在生成對抗網絡(GAN)課程中說過:「……本質上,GAN 就是另一種損失函數。」
  • 寫Python 代碼不可不知的函數式編程技術
    如果你對函數式編程並不熟悉,可以先閱讀這篇文章:https://medium.com/@yannickdot/functional-programming-101-6bc132674ec5。本文作者是新加坡國立大學計算機學院和「USP」博學計劃學生 Raivat Shah,專注於編程與數據研究。
  • Java8特性之方法引用
    然而,直到今日仍有許多軟體開發者對其相關特性不了解,這可能主要是Java基礎教材更新緩慢的原因。為了使大家對與Java8的特性有全面系統的了解,本公眾號將連續幾篇文章介紹Java8中的各個特性。Java8中新增的特性主要有:Lambda 表達式 − Lambda允許把函數作為一個方法的參數(函數作為參數傳遞進方法中。