Java8的Lambda表達(dá)式你真的會(huì)嗎
理解Lambda
Lambda表達(dá)式可以是一段可以傳遞的代碼,它的核心思想是將面向?qū)ο笾械膫鬟f數(shù)據(jù)變成傳遞行為,也就是行為參數(shù)化,將不同的行為作為參數(shù)傳入方法。
隨著函數(shù)式編程思想的引進(jìn),Lambda表達(dá)式讓可以用更加簡(jiǎn)潔流暢的代碼來代替之前冗余的Java代碼。
口說無憑,直接上個(gè)例子吧。在Java8之前,關(guān)于線程代碼是這樣的:
class Task implements Runnable{
@Override
public void run() {
System.out.println("Java8 之前 實(shí)現(xiàn)Runnable接口中的run方法");
}
}
Runnable t = new Task();
我們定義了一個(gè)Task類,讓它實(shí)現(xiàn)Runnable接口,實(shí)現(xiàn)僅有的run方法,我們希望執(zhí)行的線程體雖然只有一句話,但我們?nèi)匀换舜罅看蟠a去定義。為了簡(jiǎn)化,我們可以采用匿名內(nèi)部類的方式:
Runnable taskBeforeJava8 = new Runnable() {
@Override
public void run() {
System.out.println("Java8 之前的寫法, 傳入匿名類");
}
};
但是,其實(shí)還是不夠簡(jiǎn)潔,我們用Lambda的寫法是這樣的:
// java8 之后
Runnable taskAfterJava8 = () -> System.out.println("Java8 之后的寫法,lambda表達(dá)式");
我們僅僅使用()和->就完成了這件事,是不是非常簡(jiǎn)潔呢?如果你覺得雖然Lambda寫法簡(jiǎn)潔,但是它的規(guī)則讓人摸不著頭腦,那就跟著我接下去學(xué)叭。
基礎(chǔ)語(yǔ)法
(parameters) -> action
(parameters) -> expression
(parameters) -> {statements;}
parameters代表變量,可以為空,可以為單,可以為空,你能想到的方式他都可以。
action是實(shí)現(xiàn)的代碼邏輯部分,可以是一行代碼expression,也可以是一個(gè)代碼片段statements。如果是代碼片段,需要加上{}。
下面是一些合法的示例,你可以看看有沒有掌握:
| 表達(dá)式 | 描述 |
|---|---|
| () -> 1024 | 不需要參數(shù),返回值為1024 |
| x -> 2 * x | 接收參數(shù)x,返回其兩倍 |
| (x, y) -> x - y | 接收兩個(gè)參數(shù),返回它們的差 |
| (int x, int y) -> x + y | 接收兩個(gè)int類型參數(shù),返回他們的和 |
| (String s) -> print(s) | 接收一個(gè)String對(duì)象,并打印 |
函數(shù)式接口
@FunctionalInterface // 此注解作用的接口 只能擁有一個(gè)抽象方法
public interface Runnable {
public abstract void run();
}
在這里,@FunctionalInterface注解是非必須的,有點(diǎn)類似于@Override,起強(qiáng)調(diào)作用,如果你的接口標(biāo)注該注解,卻沒有遵循它的原則,編譯器會(huì)提示你修改。
常用的函數(shù)式接口
JDK原生為我們提供了一些常用的函數(shù)式編程接口,讓我們?cè)谑褂盟麄兙幊虝r(shí),不必關(guān)心接口名,方法名,參數(shù)名,只需關(guān)注它的參數(shù)類型,參數(shù)個(gè)數(shù),返回值。
| 接口 | 參數(shù) | 返回值 | 類別 | 示例 |
|---|---|---|---|---|
| Consumer | T | void | 消費(fèi)型接口 | 打印輸出某個(gè)值 |
| Supplier | None | T | 供給型接口 | 工廠方法獲取一個(gè)對(duì)象 |
| Function | T | R | 函數(shù)型接口 | 獲取傳入列表的總和 |
| Predicate | T | boolean | 斷言型接口 | 判斷是否以summer為前綴 |
消費(fèi)型接口
@FunctionalInterface // 此注解作用的接口 只能擁有一個(gè)抽象方法
public interface Runnable {
public abstract void run();
}
供給型接口
/**
* 供給型接口, 無參數(shù),返回T
*/
public static void supplierTest() {
Supplier<Object> supplier = () -> new Object();
System.out.println(supplier.get());
}
斷言型接口
/**
* 斷言型 傳入?yún)?shù)T ,返回boolean
*/
public static void predicateTest() {
Predicate<String> predicate = name -> name.startsWith("summer");
System.out.println(predicate.test("summerday"));
}
函數(shù)型接口
/**
* 函數(shù)型接口 傳入T 返回R
*/
public static void functionTest() {
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Function<List<Integer>, Integer> function = num -> {
int res = 0;
for (int n : list) {
res += n;
}
return res;
};
Integer num = function.apply(list);
System.out.println(num);
}
方法引用
方法引用可以看作特定Lambda表達(dá)式的快捷寫法,主要分為以下兩種:
- 指向靜態(tài)方法的方法引用
- 指向現(xiàn)有對(duì)象的實(shí)例方法的方法引用
/**
* 方法引用
* 1. 指向靜態(tài)方法的方法引用
* 2. 指向現(xiàn)有對(duì)象的實(shí)例方法的方法引用
*
* @author Summerday
*/
public class MethodReferenceTest {
public static List<String> getList(List<String> params, Predicate<String> filter) {
List<String> res = new LinkedList<>();
for (String param : params) {
if (filter.test(param)) {
res.add(param);
}
}
return res;
}
// 靜態(tài)方法
public static boolean isStartWith(String name) {
return name.startsWith("sum");
}
public static void main(String[] args) {
List<String> params = Arrays.asList("summerday","tqbx","天喬巴夏","summer","");
//靜態(tài)方法的方法引用 getList(params, name -> MethodReferenceTest.isStartWith(name));
List<String> list = getList(params, MethodReferenceTest::isStartWith);
System.out.println(list);
// 指向現(xiàn)有對(duì)象的實(shí)例方法的方法引用 getList(params, name -> name.isEmpty());
List<String> sum = getList(params, String::isEmpty);
System.out.println(sum);
}
}
數(shù)組引用
/**
* 數(shù)組引用
* @author Summerday
*/
public class ArrayReferenceTest {
public static void main(String[] args) {
// 普通lambda
Function<Integer,String[]> fun1 = x -> new String[x];
String[] res1 = fun1.apply(10);
System.out.println(res1.length);
// 數(shù)組引用寫法
Function<Integer,String[]> fun2 = String[]::new;
String[] res2 = fun2.apply(10);
System.out.println(res2.length);
}
}
構(gòu)造器引用
/**
* 構(gòu)造器引用
* @author Summerday
*/
public class ConstructorReferenceTest {
public static void main(String[] args) {
// 普通lambda
Supplier<User> sup = () -> new User();
// 構(gòu)造器引用
Supplier<User> supplier = User::new;
User user = supplier.get();
System.out.println(user);
}
}
class User{
}
總結(jié)
- lambda表達(dá)式?jīng)]有名稱,但有參數(shù)列表,函數(shù)主體,返回類型,可能還有一個(gè)可以拋出的異常的列表。
- lamda表達(dá)式讓你可以將不同的行為作為參數(shù)傳入方法。
- 函數(shù)式接口是僅僅聲明了一個(gè)抽象方法的接口。只有在接受函數(shù)式接口的地方才可以使用lambda表達(dá)式。
- lambda表達(dá)式允許你直接內(nèi)聯(lián),為函數(shù)式接口的抽象方法提供實(shí)現(xiàn),并將整個(gè)表達(dá)式作為函數(shù)式接口的一個(gè)實(shí)例。
- Java8自帶了一些常用的函數(shù)式接口,包括
Predicate,Function,Supplier,Consumer,BinaryOperator。 - 方法引用讓你重復(fù)使用現(xiàn)有的方法實(shí)現(xiàn)并直接傳遞他們:
Classname::method。
到此這篇關(guān)于Java8的Lambda表達(dá)式你真的會(huì)嗎的文章就介紹到這了,更多相關(guān)Java8的Lambda表達(dá)式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JAVA8 lambda表達(dá)式權(quán)威教程
- Java8新特性之Lambda表達(dá)式的使用
- Java8新特性:Lambda表達(dá)式之方法引用詳解
- java8 forEach結(jié)合Lambda表達(dá)式遍歷 List操作
- Java8 Lambda表達(dá)式模板方法實(shí)現(xiàn)解析
- Java8 lambda表達(dá)式2種常用方法代碼解析
- 詳解Java8中的Lambda表達(dá)式
- Java8 用Lambda表達(dá)式給List集合排序的實(shí)現(xiàn)
- Java8中Lambda表達(dá)式使用和Stream API詳解
- Java8與Scala中的Lambda表達(dá)式深入講解
- java8學(xué)習(xí)教程之lambda表達(dá)式的使用方法
- 簡(jiǎn)單易懂的java8新特性之lambda表達(dá)式知識(shí)總結(jié)
相關(guān)文章
前端發(fā)送的請(qǐng)求Spring如何返回一個(gè)文件詳解
這篇文章主要給大家介紹了關(guān)于前端發(fā)送的請(qǐng)求Spring如何返回一個(gè)文件的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-09-09
Quarkus集成Dubbo服務(wù)Rpc遠(yuǎn)程通訊框架整合
這篇文章主要為大家介紹了Quarkus集成Dubbo服務(wù)Rpc遠(yuǎn)程通訊框架的整合,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-02-02
OpenCV Java實(shí)現(xiàn)人臉識(shí)別和裁剪功能
這篇文章主要為大家詳細(xì)介紹了OpenCV Java實(shí)現(xiàn)人臉識(shí)別和裁剪功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
java.lang.Runtime.exec() Payload知識(shí)點(diǎn)詳解
在本篇文章里小編給大家整理的是一篇關(guān)于java.lang.Runtime.exec() Payload知識(shí)點(diǎn)相關(guān)內(nèi)容,有興趣的朋友們學(xué)習(xí)下。2020-03-03
java存儲(chǔ)以及java對(duì)象創(chuàng)建的流程(詳解)
下面小編就為大家?guī)硪黄猨ava存儲(chǔ)以及java對(duì)象創(chuàng)建的流程(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05
SpringBoot整合Javamail實(shí)現(xiàn)郵件發(fā)送功能
郵件發(fā)送是一個(gè)很普遍的功能,springboot整合了相關(guān)的starter,本文給大家介紹了可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的郵件發(fā)送功能的實(shí)例,文中通過代碼給大家介紹的非常詳細(xì),感興趣的朋友可以參考下2023-12-12
Java中BigDecimal的舍入模式解析(RoundingMode)
這篇文章主要介紹了Java中BigDecimal的舍入模式解析(RoundingMode),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Mybatis-Plus自動(dòng)填充的實(shí)現(xiàn)示例
這篇文章主要介紹了Mybatis-Plus自動(dòng)填充的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08

