深入理解Java8新特性之Lambda表達(dá)式的基本語法和自定義函數(shù)式接口
1.寫在前面
目前我們學(xué)習(xí)Java主要用到的應(yīng)該就是Java8了,或者說大部分企業(yè)當(dāng)前使用的也是Java8。那么既然Java8的應(yīng)用如此之廣泛,一定有一些亮點所在:
- Lambda 表達(dá)式
- 函數(shù)式接口
- 方法引用與構(gòu)造器引用
- Stream API
- 接口中的默認(rèn)方法與靜態(tài)方法
- 新時間日期API
- 其他新特性
速度更快、代碼更少(增加了新的語法 Lambda 表達(dá)式)、強大的 Stream API、便于并行、最大化減少空指針異常 Optional。
2.為什么要使用Lambda表達(dá)式?
Lambda 是一個 匿名函數(shù) 數(shù),我們可以把 Lambda表達(dá)式理解為是 一段可以傳遞的 代碼(將代碼像數(shù)據(jù)一樣進(jìn)行傳遞)。可以寫出更簡潔、更靈活的代碼。作為一種更緊湊的代碼風(fēng)格,使Java語言表達(dá)能力得到了提升。
3.Lambda表達(dá)式的基本語法
Lambda 表達(dá)式在Java 語言中引入了一個新的語法元素和操作符。這個操作符為 “ -> ” , 該操作符被稱為 Lambda 操作符或剪頭操作符。
它將 Lambda 分為兩個部分:
- 左側(cè) :指定了 Lambda 表達(dá)式需要的所有參數(shù)。
- 右側(cè) :指定了 Lambda 體,即 Lambda 表達(dá)式要執(zhí)行的功能。
具體的就看下面的代碼案例。
package com.szh.java8;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* Lambda 表達(dá)式的基礎(chǔ)語法:
* Java8中引入了一個新的操作符 "->"
* 該操作符稱為 箭頭操作符 或 Lambda操作符
* 箭頭操作符將 Lambda 表達(dá)式拆分成兩部分:
*
* 左側(cè):Lambda 表達(dá)式的參數(shù)列表
* 右側(cè):Lambda 表達(dá)式中所需執(zhí)行的功能, 即 Lambda 體
*
* Lambda 表達(dá)式需要“函數(shù)式接口”的支持
* 函數(shù)式接口:接口中只有一個抽象方法的接口, 稱為函數(shù)式接口
* 可以使用注解 @FunctionalInterface 修飾, 可以檢查是否是函數(shù)式接口
*/
public class MyTest2 {
/**
* 語法格式一:無參數(shù),無返回值
* () -> System.out.println("Hello World!!!");
*/
@Test
public void test1() {
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!!!");
}
};
r1.run();
System.out.println("---------------------------");
Runnable r2 = () -> System.out.println("Hello World!!!");
r2.run();
}
}

package com.szh.java8;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* Lambda 表達(dá)式的基礎(chǔ)語法:
* Java8中引入了一個新的操作符 "->"
* 該操作符稱為 箭頭操作符 或 Lambda操作符
* 箭頭操作符將 Lambda 表達(dá)式拆分成兩部分:
*
* 左側(cè):Lambda 表達(dá)式的參數(shù)列表
* 右側(cè):Lambda 表達(dá)式中所需執(zhí)行的功能, 即 Lambda 體
*
* Lambda 表達(dá)式需要“函數(shù)式接口”的支持
* 函數(shù)式接口:接口中只有一個抽象方法的接口, 稱為函數(shù)式接口
* 可以使用注解 @FunctionalInterface 修飾, 可以檢查是否是函數(shù)式接口
*/
public class MyTest2 {
/**
* 語法格式二:有一個參數(shù),無返回值
* (x) -> System.out.println(x)
* 此語法格式中小括號可以省略不寫,等價于
* x -> System.out.println(x)
*/
@Test
public void test2() {
Consumer<String> consumer = (str) -> System.out.println(str);
consumer.accept("Lambda表達(dá)式真好用....");
}
}

package com.szh.java8;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* Lambda 表達(dá)式的基礎(chǔ)語法:
* Java8中引入了一個新的操作符 "->"
* 該操作符稱為 箭頭操作符 或 Lambda操作符
* 箭頭操作符將 Lambda 表達(dá)式拆分成兩部分:
*
* 左側(cè):Lambda 表達(dá)式的參數(shù)列表
* 右側(cè):Lambda 表達(dá)式中所需執(zhí)行的功能, 即 Lambda 體
*
* Lambda 表達(dá)式需要“函數(shù)式接口”的支持
* 函數(shù)式接口:接口中只有一個抽象方法的接口, 稱為函數(shù)式接口
* 可以使用注解 @FunctionalInterface 修飾, 可以檢查是否是函數(shù)式接口
*/
public class MyTest2 {
/**
* 語法格式三:有兩個以上的參數(shù),有返回值,并且 Lambda 體中有多條語句
*/
@Test
public void test3() {
Comparator<Integer> comparator = (x,y) -> {
System.out.println("函數(shù)式接口....");
return Integer.compare(x,y);
};
}
}
package com.szh.java8;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* Lambda 表達(dá)式的基礎(chǔ)語法:
* Java8中引入了一個新的操作符 "->"
* 該操作符稱為 箭頭操作符 或 Lambda操作符
* 箭頭操作符將 Lambda 表達(dá)式拆分成兩部分:
*
* 左側(cè):Lambda 表達(dá)式的參數(shù)列表
* 右側(cè):Lambda 表達(dá)式中所需執(zhí)行的功能, 即 Lambda 體
*
* Lambda 表達(dá)式需要“函數(shù)式接口”的支持
* 函數(shù)式接口:接口中只有一個抽象方法的接口, 稱為函數(shù)式接口
* 可以使用注解 @FunctionalInterface 修飾, 可以檢查是否是函數(shù)式接口
*/
public class MyTest2 {
/**
* 語法格式四:若 Lambda 體中只有一條語句,
* 則 return 和 大括號都可以省略不寫
* Lambda 表達(dá)式的參數(shù)列表的數(shù)據(jù)類型可以省略不寫,
* 因為JVM編譯器通過上下文推斷出,數(shù)據(jù)類型,即 “類型推斷”
*/
@Test
public void test4() {
Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
}
}
上述 Lambda 表達(dá)式中的參數(shù)類型都是由編譯器推斷得出的。Lambda 表達(dá)式中無需指定類型,程序依然可以編譯,這是因為 javac 根據(jù)程序的上下文,在后臺
推斷出了參數(shù)的類型。Lambda 表達(dá)式的類型依賴于上下文環(huán)境,是由編譯器推斷出來的。這就是所謂的 “類型推斷”。
4.自定義函數(shù)式接口
只包含一個抽象方法的接口,稱為 函 數(shù) 式 接 口。
你可以通過 Lambda 表達(dá)式來創(chuàng)建該接口的對象。(若 Lambda表達(dá)式拋出一個受檢異常,那么該異常需要在目標(biāo)接口的抽象方法上進(jìn)行聲明)
我們可以在任意函數(shù)式接口上使用 @FunctionalInterface 注解,這樣做可以檢查它是否是一個函數(shù)式接口,同時 javadoc 也會包含一條聲明,說明這個接口是一個函數(shù)式接口。
就像Runnable接口一樣,它就是一個典型的函數(shù)式接口。
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface {@code Runnable} is used
* to create a thread, starting the thread causes the object's
* {@code run} method to be called in that separately executing
* thread.
* <p>
* The general contract of the method {@code run} is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
那么我們肯定也可以自定義函數(shù)式接口了,首先是沒有泛型的自定義函數(shù)式接口。
package com.szh.java8.two;
/**
*
*/
@FunctionalInterface
public interface MyFunction {
public String getValue(String str);
}
package com.szh.java8.two;
/**
*
*/
public class TestLambda {
private static String strHandler(String str,MyFunction mf) {
return mf.getValue(str);
}
public static void main(String[] args) {
//去除首尾空格
String trimStr = strHandler("\t\t\t 張起靈-小哥 ",(str) -> str.trim());
System.out.println(trimStr);
//轉(zhuǎn)為大寫
String upperStr = strHandler("hello world",str -> str.toUpperCase());
System.out.println(upperStr);
//部分截取
String newStr = strHandler("學(xué)Java的冷少",(str) -> str.substring(0,5));
System.out.println(newStr);
}
}

下面再來看一個帶泛型的函數(shù)式接口。
package com.szh.java8.three;
/**
*
*/
@FunctionalInterface
public interface MyFunction2<T,R> {
public R getValue(T t1,T t2);
}
package com.szh.java8.three;
import com.szh.java8.two.MyFunction;
/**
*
*/
public class TestLambda {
private static void operation(Long l1,Long l2,MyFunction2<Long,Long> mf) {
System.out.println(mf.getValue(l1,l2));
}
public static void main(String[] args) {
//和
operation(100L,200L,(x,y) -> x + y);
//積
operation(300L,500L,(x,y) -> x * y);
}
}

作為參數(shù)傳遞 Lambda 表達(dá)式:為了將 Lambda 表達(dá)式作為參數(shù)傳遞 ,接收 Lambda 表達(dá)式的參數(shù)類型必須是與該 Lambda 表達(dá)式兼容的函數(shù)式接口的類型。
以上就是深入理解Java8新特性之Lambda表達(dá)式的基本語法和自定義函數(shù)式接口的詳細(xì)內(nèi)容,更多關(guān)于Java Lambda表達(dá)式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot 2.0.0 終于正式發(fā)布-重大修訂版本
北京時間 2018 年 3 月 1 日早上,如約發(fā)布的 Spring Boot 2.0 在同步至 Maven 倉庫時出現(xiàn)問題,導(dǎo)致在 GitHub 上發(fā)布的 v2.0.0.RELEASE 被撤回2018-03-03
淺談String類型等值比較引起的“==”、“equals()”和“hashCode”思考
這篇文章主要介紹了淺談String類型等值比較引起的“==”、“equals()”和“hashCode”思考。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
springboot的application.yml配置port不生效的解決方案
這篇文章主要介紹了springboot的application.yml配置port不生效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
淺析Java中對象的創(chuàng)建與對象的數(shù)據(jù)類型轉(zhuǎn)換
這篇文章主要介紹了Java中對象的創(chuàng)建與對象的數(shù)據(jù)類型轉(zhuǎn)換,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01
Springboot?HTTP如何調(diào)用其他服務(wù)
這篇文章主要介紹了Springboot?HTTP如何調(diào)用其他服務(wù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01

