寫在前面
還記得上次面試時被問到Java8新特性,我當時居然腦袋一片空白锄弱,然后就GAME OVER了。剛走到大門口才想起來Lambda表達式這個點肖卧,真的是有點失望掸鹅,現(xiàn)在想想主要原因是自己在項目中沒有使用,只是停留在了解層面巍沙,沒有用到項目其實就是就是不會!句携!
就像這Markdown編輯器一個月沒 寫博客,都不會用了削咆。尷尬,一不小心就暴露自己的懶拨齐。
好了廢話少說,開始搞正事厦滤。
Java8新特性中的其他特性歼狼,這里就不說了,主要原因是不能兼容Android7.0以下蹂匹。
Lambda表達式說白了就是一種匿名方法,不需要方法名忍啸,修飾符履植,和返回值類型。
使用方法
首先在moudle的build.gradle文件中添加配置:app/build.gradle添加玫霎。
android {
...
defaultConfig {
...
jackOptions.enabled=true;
}
compileOptions{
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
...
}
就這樣配置就OK了;
接下來我們來看看怎么使用翁脆;
首先拿一個點擊事件來比對一下:
一般寫法
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
解說:這是一種匿名內(nèi)部類的寫法鼻种,較之外部類的寫法已經(jīng)算是很簡潔了。
Lambda表達式*
button.setOnClickListener(view ->{
});
解說:不難發(fā)現(xiàn)叉钥,Lambda的這種寫法連匿名內(nèi)部類都不用寫了,更加簡潔了枫疆,直接將參數(shù)暴露在外敷鸦,在方法體中可以直接調(diào)用該參數(shù)寝贡;如果沒有參數(shù)就用()就行钞螟,例如開啟線程的寫法:
new Thread(() -> {
});
到這里大家可能就要說了:不就是少了兩行代碼谎碍,有什么了不起,學的時候還不是要從匿名內(nèi)部類寫起蟆淀?
放個大招給你們瞅瞅,在點擊事件中開啟一個線程的:
一般寫法
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
}
});
}
});
看起來是不是有點眼花繚亂褒链,很明顯的onClick等方法有點搶鏡疑苔,讓run方法不是那么容易被發(fā)現(xiàn);
Lambda表達式
button.setOnClickListener( view-> new Thread(() -> {
}));
怎么樣兵迅,是不是被驚艷到了薪贫,服不服?瞧省?Lambda就是這么簡潔,簡潔到?jīng)]朋友鞍匾。
可能有朋友就奇怪怎么寫一起了,不該是兩個分開的Lambda表達式构拳,像這樣嗎梳码,嵌套在一起怎么變樣了?
button.setOnClickListener(view -> {
new Thread(() -> {
});
});
帶著這個疑問我們從源頭找起掰茶,來看看Lambda表達式到底簡化了什么?
從上面幾個例子我們不難發(fā)現(xiàn)盐碱,Lambda表達式的簡化,其實是簡化了接口的匿名內(nèi)部類的實現(xiàn)和方法:
//一般寫法
View.OnClickListener listener=new View.OnClickListener() {
@Override
public void onClick(View view) {
}
};
//Lambda表達式
View.OnClickListener listener= view -> {
};
比如在這里Lambda簡化了OnClickListener這個接口的匿名實現(xiàn)和一個必須實現(xiàn)的方法onClick县好,只留下一個參數(shù)View暖混。
那么 到這里,我們大概了解了Lambda表達式的作用拣播,但是心中卻產(chǎn)生了疑問,Lambda表達式的使用范圍廣不廣谍倦?
比如下面提出的一些疑問:
- Lambda表達式只能簡化接口的匿名實現(xiàn)嗎泪勒?
- Lambda表達式能簡化多個方法的接口的匿名實現(xiàn)嗎?
- Lambda表達式能簡化方法里有多個參數(shù)的接口嗎圆存?
- Lambda表達式能簡化方法帶有返回值的接口嗎?
OK送淆,接下來我們來一一解答:
Lambda表達式只能簡化接口的匿名實現(xiàn)嗎怕轿?
答案是肯定的。
就目前而言Lambda表達式只能簡化接口的匿名內(nèi)部類實現(xiàn)撞羽。
原因大概是:接口是沒有構(gòu)造方法,而抽象類和一般的類是有構(gòu)造方法的谒出;接口里的方法沒有方法體等等邻奠。因為接口的特殊性,Lambda表達式就是只針對接口而已碌宴。
Lambda表達式能簡化多個方法的接口的匿名實現(xiàn)嗎?
答案是不能:這里從Lambda的表達式就可以看出來呜象,已經(jīng)簡化到?jīng)]有沒有一絲多余的代碼,多個方法怎么寫呢恭陡。
結(jié)論:
Lambda只能簡化了單一方法接口的實現(xiàn),以及方法的匿名實現(xiàn)著淆;
Lambda表達式能簡化多個參數(shù)的單一方法接口嗎哥捕?
這個答案是肯定的。
前面我在例子中已經(jīng)用到了沒有參數(shù)和一個參數(shù)的接口匿名實現(xiàn)遥赚。
- 沒有參數(shù)一個空的小括號阐肤;
- 一個參數(shù)在括號里面添加一個參數(shù),
- 多個參數(shù)就直接添加就OK了愧薛;
- 一個參數(shù)時小括號是可以省略的衫画;
- 另外參數(shù)類型是可以省略的,當然也就可以寫的削罩;
- 省略括號時是不能寫參數(shù)類型的。
示例如下:
//沒有參數(shù)
Runnable runnable=() -> {
};
//一個參數(shù)
View.OnClickListener listener= (View view) -> {
};
View.OnClickListener listener= (view) -> {
//參數(shù)類型可省略
};
View.OnClickListener listener= view -> {
//括號可省略进陡,但不能添加參數(shù)
};
//兩個參數(shù)
public interface JackListener{
void check(String string,String check);
};
doWhat("jack666", (string, check) -> {
//這里的兩個參數(shù)指的是接口里方法的參數(shù)微服,而不是doWhat的參數(shù)哦
});
Lambda表達式能簡化方法帶有返回值的接口嗎?
答案是肯定的糙麦,其實返回值和簡化前的寫法是一樣丛肮,return一下就可以了。
示例如下:
//兩個參數(shù)
public interface JackListener{
boolean check(String string,String check);
};
doWhat("jack666", (string, check) -> {
boolean result=string.contains(check);
Toast.makeText(MainActivity.this, ""+result, Toast.LENGTH_SHORT).show();
return result;
});
解答完上述幾個問題腾供,我們也就了解了Lambda表達式使用范圍是針對單一方法接口的匿名實現(xiàn)鲜滩,是有很強的針對性节值,并不是哪里都能用的,不過就目前的面向接口編程的大環(huán)境下還是有不小的使用空間嗓蘑。
那現(xiàn)在咱們再來看看最前面的那個問題:兩個Lambda表達式嵌套時匿乃,發(fā)生的化學反應:
button.setOnClickListener(view -> {
new Thread(() -> {
});
});
//兩個Lambda表達式嵌套,極簡模式
button.setOnClickListener( view-> new Thread(() -> {
//前提是Lambda表達式中的方法體內(nèi)部只有一個單純Lambda表達式
}));
到這里幢炸,不難發(fā)現(xiàn)外層Lambda表達式的方法體被簡化了,而將內(nèi)部的Lambda表達式銜接在了外層后面佛嬉,就形成了這種極簡的寫法闸天;
那么Lambda表達式能簡化多個Lambda表達式的嵌套嗎,帶著好奇心苞氮,我嘗試了四個Lambda表達式的嵌套:
//一般寫法
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
}
});
}
});
}
});
}
});
//四個Lambda表達式嵌套笼吟,CRAZY!!!
button.setOnClickListener(view -> new Thread(() ->
button.setOnClickListener(view1 -> new Thread(() -> {
}))));
當然像這種多層嵌套在開發(fā)環(huán)境中極少能遇到,知道Lambda表達式可以簡化多層嵌套就OK了赞厕。
寫在后面:
從Lambda表達式開始等于開啟了Java的極簡模式,期待下個版本會有更多的簡化毫目,祝福Java在簡化這條路上越走越遠诲侮,讓嘲笑Java臃腫的人去屎!
一句話總結(jié):
Lambda簡化了單一方法接口的匿名內(nèi)部類實現(xiàn)沟绪,以及單一方法的匿名實現(xiàn);