Functional interface for Lambda

In this blog, I would like to explain how Lambda functions work in Java, and how we can use them.

Functional interface

When talking about Lambda’s , the first thing to understand is the Functional Interface. As this is the sort of interface you would be using, when using Lambda’s. In fact Lambda’s define the implementation of a functional interface.

Java versions prior to 8 had SAM-interfaces : Single Abstract Method-interfaces. As the definition speaks for itself, it’s an interface with 1 abstract method. In Java 8, the concept of SAM-interfaces has been re-created and called “functional interfaces”.

You can write a functional interface yourself, but some already provided by the Java language via the java.util.function package, and used in different API’s.

  • Definition
    A functional interface is an interface with exactly 1 abstract method. The interface can have other methods, but they would have to be default methods, meaning that they would have their implementation in the interface itself. (This is also a new feature in Java 8.)
  • Example
    When writing a functional interface yourself, it’s a good practice to annotate it with @FunctionalInterface. This annotation is used to generate compiler level errors when the interface has more than 1 abstract method in your interface. The annotation is not required, but improves the readability of your code. For example:
    @FunctionalInterface
    interface Calculator {
    public double calculate(double val1, double val2);
    }
    
    If you would add another abstract method, you would get a compile time error: Invalid ‘@FunctionalInterface’ annotation; MyCalculator is not a functional interface
    We could add a few default method’s, and the interface will still remain a functional interface:
    @FunctionalInterface
    interface Calculator {
       public double calculate(double val1, double val2);
       default public void print(String str) {
          System.out.println("The print method prints "+str);
       }
       default public void print(double val1, double val2) {
          System.out.println("The print method prints "+val1+" "+val2);
       }
    }
    
    So we have written a functional interface with a method that takes a 2 doubles and returns a double. Now let’s create an implementation for this interface, the ‘old school’ way:
    Calculator multiply = new Calculator() {
        public double calculate(double val1, double val2) {
                return val1 * val2;
        }
    };
    Calculator sum = new Calculator() {
        public double calculate(double val1, double val2) {
                return val1 + val2;
        }
    };
    
    With Lamba functions it looks like this:
    Calculator multiply = (val1, val2) -> val1 * val2;
    Calculator sum = (val1, val2) -> val1 + val2;
    
    Notice that we removed the double declaration of the parameters, as the java compiler can defer those from the interface.
    Now let’s use our classes:
    System.out.println("multiply = "+multiply.calculate(5,6));
     This line executes 5*6, so it prints out “multiply = 30.0”
    
    System.out.println("sum = "+sum.calculate(5,6));
    this line executes 5+6, so it prints out “sum = 11.0”
    
  • The Java API way
    The java.util.function package contains functional interfaces that are used throughout the Java API. I’ll explain the Function, Consumer, Supplier, and Predicate as those are the ones that are mostly used in the Java API. We’ll use them in the next chapter where we demonstrate how to use them in the Stream API, an Java API that makes a lot of use of Lambda’s.

1.Function

So let’s start exploring the possibilities and usages of the lambda function’s in Java. As stated before, the java.util.function packages contains functional interfaces, and in this chapter I’d like to explain how to use them.
If you look at the abstract method of the Function interface, you see It looks like this: R apply(T t) . This method does nothing more then take an argument and returns a result. So we could write the following:

Function plus5 = (i -> i+5);
Integer var1 = plus5(1);

This function class will take an Integer, and return that integer+5. As we saw that the apply is the abstract function, i+5 is the implementation for that function. So that means that Line 2 will set var1 to 6. When we want more than 1 line code in the lamda function, we’ll need to use curly brackets.

Function plus5 = (i ->  { 
                System.out.println(" Integer=" + i);
               return i+5; 
});
Integer var1 = plus5(1);

If we execute the code on the last line, it will first, print ‘5’ to the console, and then, set integer var1 to 6.

Now that we know how to use a Function, let’s have a look at another interesting method in this interface :
default Function andThen(Function after)
This is a default method, meaning that it has its implementation in the Function interface class. Using this method, we can execute multiple functions in a chain. This is well illustrated when adding a print out in the Lamda.

Function plus5 = (i ->  { 
                System.out.println("Before plus 5 = " + i);
               return i+5;
         });
Function min2 = (i ->  { 
                System.out.println("Before min2 " + i);
               return i-5;
         });
Function plus10 = (i ->  { 
                System.out.println("Before plus10 " + i);
               return i+10;
         });
Integer var1 = plus5.andThen(min2).andThen(plus10).apply(100);
System.out.println("var1="+var1);

When executing this code, we’ll see the following output on the console :

Line 1 : before plus 5 = 100
Line 2 : before min2 105
Line 3 : before plus10 103
Line 4 : var1=113

So we execute plus5 with value 100, which prints Line 1.
andThen we execute min2 method (Line 2), entered with the new value 105 (5 added by the apply method)
andThen we execute plus10 method (Line 3), entered with the new value 103 (minus 2 by the first andThen method)
final result is 113, as 10 was added to 103 by the plus10.

2.Consumer

The java.util.function.Consumer interface is a bit like the Function, only it doesn’t returns any values. It just ‘consumes’ an object. Looking at the API, the abstract method is the following : void accept (T t) . So using our Lambda’s here:

Consumer printConsumer = str ->  System.out.println("str =" + str);
printConsumer.accept(“Hello Lambda”);

This will print: str=Hello Lambda
As you can see, we give the consumer a String as input, and it does something with it : print it out. As Function, the Consumer also has the ability to chain actions using a andThen method:

Consumer c1 = i ->  System.out.println("C1 Integer =" + i);
Consumer c2 = i ->  System.out.println("C2 Integer =" + (i+1));
Consumer c3 = i ->  System.out.println("C3 Integer =" + (i+5));
c1.andThen(c2).andThen(c2).andThen(c3).andThen(c2).accept(100);

This will print out the following to the console :

C1 Integer =100
C2 Integer =101
C2 Integer =101
C3 Integer =105
C2 Integer =101
First the accept of c1 is executed, then twice c2, adding 1 each time then C3, adding 5, and after c3 , c2 is executed again, adding 1.

3.Supplier

Next, we have the Supplier. This interface does not take any parameters, but only produces an output result.
Looking at the API we see following abstract method : T get() . Now here’s an example of a supplier, that supplies us with a random number:

Supplier random = () -> new Random().nextInt();
System.out.println("random integer:"+random.get());

This will print out the following to the console : random integer:1020054503
As there is no parameter passed to the method , we use the syntax “()” before the arrow to indicate this.

4.Predicate

Finally there is the Predicate interface. The abstract method here is boolean Test(T t) . So it takes an object, and returns a primitive Boolean.

Predicate equals5 = i -> i==5;
System.out.println("Is equal to 5 ? "+equals5.test(7));

This will print out the following to the console :Is equal to 5 ? false
Now we can also use this in a chain with and or or:

Predicate equals10 = i -> i==10;
System.out.println("Is equal to 5 or 10 ? "+equals5.or(equals10).test(5));

This will print out the following to the console : Is equal to 5 or 10 ? true

Conclusion

So in this article, I explained the very basics of Lambda functions. If you understand this, you’re ready for the great Lambda experience.
This is copied by Hugo from https://www.jstack.eu/blog. And also I don't wanna to translate it.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末尤误,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子掏父,更是在濱河造成了極大的恐慌兜叨,老刑警劉巖档玻,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躏率,死亡現(xiàn)場(chǎng)離奇詭異躯畴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)薇芝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門蓬抄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人夯到,你說(shuō)我怎么就攤上這事嚷缭。” “怎么了耍贾?”我有些...
    開(kāi)封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵阅爽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我逼争,道長(zhǎng)优床,這世上最難降的妖魔是什么劝赔? 我笑而不...
    開(kāi)封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任誓焦,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘杂伟。我一直安慰自己移层,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布赫粥。 她就那樣靜靜地躺著观话,像睡著了一般。 火紅的嫁衣襯著肌膚如雪越平。 梳的紋絲不亂的頭發(fā)上频蛔,一...
    開(kāi)封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音秦叛,去河邊找鬼晦溪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛挣跋,可吹牛的內(nèi)容都是我干的三圆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼避咆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼舟肉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起查库,我...
    開(kāi)封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤路媚,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后樊销,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體磷籍,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年现柠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了院领。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡够吩,死狀恐怖比然,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情周循,我是刑警寧澤强法,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站湾笛,受9級(jí)特大地震影響饮怯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嚎研,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一蓖墅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦论矾、人聲如沸教翩。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饱亿。三九已至,卻和暖如春闰靴,著一層夾襖步出監(jiān)牢的瞬間彪笼,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工蚂且, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杰扫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓膘掰,卻偏偏與公主長(zhǎng)得像章姓,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子识埋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 為什么引入Lambda凡伊? 簡(jiǎn)單的來(lái)說(shuō)Lambda的引入是為了簡(jiǎn)化匿名類的編寫 什么是Lambda表達(dá)式 Lambd...
    咪啊p閱讀 327評(píng)論 0 0
  • Lambda表達(dá)式JDK8官方學(xué)習(xí)網(wǎng)址 Lambda Expressions One issue with ano...
    雨筍情緣閱讀 399評(píng)論 0 0
  • 彩排完,天已黑
    劉凱書法閱讀 4,187評(píng)論 1 3
  • 表情是什么窒舟,我認(rèn)為表情就是表現(xiàn)出來(lái)的情緒系忙。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了惠豺,難過(guò)就哭了银还。兩者是相互影響密不可...
    Persistenc_6aea閱讀 124,193評(píng)論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者,不喜歡去冒險(xiǎn)洁墙,但是人生放棄了冒險(xiǎn)蛹疯,也就放棄了無(wú)數(shù)的可能。 ...
    yichen大刀閱讀 6,033評(píng)論 0 4