Lambda 表達(dá)式
Java 8新特性簡介
- 速度更快
- 代碼更少(增加了新的語法 Lambda 表達(dá)式)
- 強(qiáng)大的 Stream API
- 便于并行
- 最大化減少空指針異常 Optional
為什么使用Lambda 表達(dá)式
Lambda 是一個匿名函數(shù),我們可以把 Lambda 表達(dá)式理解為是一段可以傳遞的代碼(將代碼 像數(shù)據(jù)一樣進(jìn)行傳遞)??梢詫懗龈啙?、更靈活的代碼。作為一種更緊湊的代碼風(fēng)格,使 Java的語言表達(dá)能力得到了提升。
從匿名類到 Lambda 的轉(zhuǎn)換
// jdk 1.7 前 ,必須是 final
int num = 0;
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(" Hello Lambda !!!"/* +num++*/);
}
};
runnable.run();
System.out.println("__________________________________");
Runnable runnable1 = () -> System.out.println(" Hello Lambda !!!"/*,num++*/);
runnable1.run();
/**
* 匿名內(nèi)部類
*/
@Test
public void test() {
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet<Integer> treeSet = new TreeSet<>(comparator);
}
/**
* Lambda
*/
@Test
public void test2() {
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
Comparator<Integer> comparator2 = Integer::compare;
TreeSet<Integer> treeSet = new TreeSet<>(comparator);
}
Lambda 表達(dá)式語法
Lambda 表達(dá)式在Java 語言中引入了一個新的語法元 素和操作符。這個操作符為 “->” , 該操作符被稱 為 Lambda 操作符或剪頭操作符。它將 Lambda 分為 兩個部分:
左側(cè):指定了 Lambda 表達(dá)式需要的所有參數(shù)
右側(cè):指定了 Lambda 體,即 Lambda 表達(dá)式要執(zhí)行 的功能
代碼演示
package com.www.java8.test;
import com.www.java8.inter.MyFun;
import com.www.java8.inter.MyFunction2;
import org.testng.annotations.Test;
import java.util.*;
import java.util.function.Consumer;
/**
* 一 、Lambda 表達(dá)式的基礎(chǔ)語法 :Java8 中引入圖了一個新的操作符 ” -> “ 該操作符稱為箭頭操作符 或 Lambda 操作符
* <p>
* 箭頭操作符將 Lambda分成了兩部分
* <p>
* 右側(cè) : Lambda 表達(dá)式的參數(shù)列表
* <p>
* 左側(cè) : Lambda 表達(dá)式中所需執(zhí)行的功能, 即 Lambda 體
* <p>
* <p>
* 語法格式一 : 無參數(shù) , 無返回值
* <p>
* () -> System.out.println("Hello Lambda ?。?)
* <p>
* <p>
* 語法格式二 : 有一個參數(shù) ,無返回值
* <p>
* (x)->System.out.println(x)
* <p>
* <p>
* 語法格式三 : 若只有一個參數(shù),小括號可以省略不寫
* <p>
* x -> System.out.println(x)
* <p>
* <p>
* 語法格式四 :有兩個以上的參數(shù), 有返回值 ,并且 Lambda 體中 有多條語句
* <p>
* <pre>
* Comparator<Integer> comparator = (x, y) -> {
* System.out.println("函數(shù)式接口?。?!");
* return Integer.compare(x, y);
* };
* </pre>
* <p>
* <p>
* 語法格式五 : 若 Lambda 體中只有一條語句, return 和 大括號 都可以省略不寫
* <p>
* <pre>
* Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
* Comparator<Integer> comparator1 = Integer::compare;
* </pre>
* <p>
* <p>
* 語法格式六: Lambda 表達(dá)式的參數(shù)列表的數(shù)據(jù)類型可以省略不寫, 因?yàn)?JVM 編譯器 可以通過上下文推斷出 數(shù)據(jù)類型, 即 ”類型推斷“
* <p>
* Comparator<Integer> comparator = (Integer x, Integer y) -> Integer.compare(x, y);
* <p>
* <p>
* <p>
* 上聯(lián) : 左右遇一括號省
* 下聯(lián) : 左側(cè)推斷類型省
* 橫批 : 能省則省
* <p>
* <p>
* <p>
* 二: Lambda 表達(dá)式需要 ”函數(shù)式接口“ 的支持
* <p>
* 函數(shù)式接口: 接口中只有一個抽象方法的接口,稱為函數(shù)式接口, 可以使用 注解 @FunctionalInterface 修飾
* 可以檢查是否為函數(shù)式接口
*
* @author Www
* <p>
* 郵箱: 483223455@qq.com
* <p>
* 創(chuàng)建時間: 2022/8/11 17:03 星期四
* <p>
*/
public class Lambda1Test {
/**
* 語法格式一 : 無參數(shù) , 無返回值
* <p>
* () -> System.out.println("Hello Lambda ?。?)
*/
@Test
public void test1() {
// jdk 1.7 前 ,必須是 final
int num = 0;
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(" Hello Lambda !!!"/* +num++*/);
}
};
runnable.run();
System.out.println("__________________________________");
Runnable runnable1 = () -> System.out.println(" Hello Lambda !!!"/*,num++*/);
runnable1.run();
}
/**
* 語法格式二 : 有一個參數(shù) ,無返回值
* <p>
* (x)->System.out.println(x)
*/
@Test
public void test2() {
Consumer<String> consumer = (x) -> System.out.println(x);
Consumer<String> consumer1 = System.out::print;
consumer1.accept("www");
}
/**
* 語法格式四 :有兩個以上的參數(shù), 有返回值 ,并且 Lambda 體中 有多條語句
* <p>
* <pre>
* Comparator<Integer> comparator = (x, y) -> {
* System.out.println("函數(shù)式接口?。?!");
* return Integer.compare(x, y);
* };
* </pre>
*/
@Test
public void test3() {
Comparator<Integer> comparator = (x, y) -> {
System.out.println("函數(shù)式接口!??!");
return Integer.compare(x, y);
};
int compare = comparator.compare(1, 2);
System.out.println(compare);
}
/**
* 語法格式五 : 若 Lambda 體中只有一條語句, return 和 大括號 都可以省略不寫
* <p>
* <pre>
* Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
* Comparator<Integer> comparator1 = Integer::compare;
* </pre>
*/
@Test
public void test4() {
Comparator<Integer> comparator = (Integer x, Integer y) -> Integer.compare(x, y);
Comparator<Integer> comparator1 = Integer::compare;
int compare = comparator1.compare(1, 333);
System.out.println(compare);
}
/**
* 類型推斷 ---> jdk 1.8 出現(xiàn); 1.7 之前不存在
*/
@Test
public void test5() {
String str[] = {"w", "ww", "www"};
String str1;
// str1={"www","ww","w"};
List<String> list = new ArrayList<>();
show(new HashMap<>());
}
public void show(Map<String, Integer> map) {
System.out.println(map.toString());
}
/**
* 對一個數(shù)進(jìn)行運(yùn)行算
*/
@Test
public void test6() {
Integer operation = operation(46, x -> x * x);
System.out.println(operation);
System.out.println(operation(919, x -> x * x));
}
/**
* 運(yùn)算方法
*
* @param num
* @param fun
* @return
*/
public Integer operation(Integer num, MyFun<Integer> fun) {
return fun.getValue(num);
}
/**
*
*/
@Test
public void test7() {
oop(46L, 919L, Long::sum);
oop(46L, 919L, (x, y) -> x * y);
}
/**
* 對兩個 Long 類型進(jìn)行處理
*
* @param l1
* @param l2
* @param fun
*/
public void oop(Long l1, Long l2, MyFunction2<Long, Long> fun) {
System.out.println(fun.getValue(l1, l2));
}
}

image.png

image.png
類型推斷
上述 Lambda 表達(dá)式中的參數(shù)類型都是由編譯器推斷 得出的。Lambda 表達(dá)式中無需指定類型,程序依然可 以編譯,這是因?yàn)?javac 根據(jù)程序的上下文,在后臺 推斷出了參數(shù)的類型。Lambda 表達(dá)式的類型依賴于上下文環(huán)境,是由編譯器推斷出來的。這就是所謂的 “ 類型推斷"