Java8 新特性-Lambda表示式
阿新 • • 發佈:2020-09-10
目錄
1、Lambda表示式介紹
package com.zjw; /** * Lambda表示式介紹 * Java 8的一個大亮點是引入Lambda表示式,使用它設計的程式碼會更加簡潔,通過Lambda表示式,可以替代我們以前經常寫的匿名內部類來實現介面。 * Lambda表示式的本質是一個匿名函式。 */ public class Lambda01 { public static void main(String[] args) { //1、通過子類建立物件 F1 f = new F1Class(); //2、使用匿名內部類 F1 f2 = new F1() { @Override public int add(int a, int b) { return a+b; } }; //3、使用Lambda表示式建立 /** * Lambda語法 * Lambda只有引數列表和方法體 * (引數列表)->{方法體} */ F1 f1 = (int a , int b)->{ return a+b; }; System.out.println(f1.add(1,2)); } } interface F1{ int add(int a , int b); } class F1Class implements F1{ @Override public int add(int a, int b) { return a+b; } }
2、Lambda表示式語法細講
使用Lambda實現不同的介面
package com.zjw; /** *Lambda表示式語法細講 * 我們搞一個案例,介面方法引數,無參,單個引數,兩個引數,有返回值,沒有返回值 */ public class Lambda02 { public static void main(String[] args) { //無返回值 無參 F1 f1 = ()->{ System.out.println("f1"); }; f1.test(); //無返回值 單參 F2 f2 = (int a)->{ System.out.println("f2="+a); }; f2.test(2); //無返回值 多參 F3 f3 = (int a , int b)->{ System.out.println("f3="+(a+b)); }; f3.test(1,2); //有返回值 無參 F4 f4 = () -> { return 4; }; System.out.println(f4.test()); //有返回值 單引數 F5 f5 = (int a)->{ return a; }; System.out.println(f5.test(5)); //有返回值 多參 F6 f6 = (int c , int d)->{ return c-d; }; System.out.println(f6.test(7,1)); } interface F1{ void test(); } interface F2{ void test(int a); } interface F3{ void test(int a , int b); } interface F4{ int test(); } interface F5{ int test(int a); } interface F6{ int test(int a , int b); } }
f1
f2=2
f3=3
4
5
6
3、 Lambda表示式語法精簡
package com.zjw; /** * Lambda語法精簡 * 1、引數型別可以省略 * 2、假如只有一個引數,()括號可以省略 * 3、如果方法體只有一條語句,{}大括號可以省略 * 4、如果方法體中唯一的語句是return語句,那省略大括號的同時return也要省略 */ public class Lambda03 { public static void main(String[] args) { F1 f1 = ()->System.out.println("f1"); f1.test(); F2 f2 = a->System.out.println("f2="+a); f2.test(2); F3 f3 = (a , b)->System.out.println("f3="+(a+b)); f3.test(1,2); F4 f4 = () -> 4; System.out.println(f4.test()); F5 f5 = a-> a; System.out.println(f5.test(5)); F6 f6 = (c , d)->c-d; System.out.println(f6.test(7,1)); } interface F1{ void test(); } interface F2{ void test(int a); } interface F3{ void test(int a , int b); } interface F4{ int test(); } interface F5{ int test(int a); } interface F6{ int test(int a , int b); } }
4、 Lambda方法引用
引用靜態方法、普通方法
package com.zjw;
/**
* 有時候多個lambda表示式實現函式是一樣的話,我們可以封裝成通用方法,以便於維護;
* 這時候可以用方法引用實現:
* 語法: 物件::方法
* 假如是static方法,可以直接 類名::方法
*/
public class Lambda04
{
public static void main(String[] args) {
Lambda04 lambda04 = new Lambda04();
F1 f1 = (a,b)-> testB(a,b);
// F1 f1 = lambda04::testA;
System.out.println(f1.test(1,2));
F1 f2 = lambda04::testA;
System.out.println(f2.test(2,3));
F1 f3 = Lambda04::testB;
System.out.println(f3.test(3,1));
}
public int testA(int a , int b){
return a+b;
}
public static int testB(int a , int b){
return a-b;
}
interface F1{
int test(int a , int b);
}
}
引用構造方法
package com.zjw;
public class Dog {
private String name;
private int age ;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public Dog() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
/**
* 如果函式式介面的實現恰好可以通過呼叫一個類的構造方法實現,那麼就可以使用構造方法引用;
* 語法: 類名::new
*/
public class Lambda05
{
public static void main(String[] args) {
DogService dogService = Dog::new;
Dog dog = dogService.getDog();
System.out.println(dog);
DogService2 dogService2 = Dog::new;
Dog dog2 = dogService2.getDog("狗狗", 2);
System.out.println(dog2);
}
interface DogService{
Dog getDog();
}
interface DogService2{
Dog getDog(String name , int age );
}
}
5、 綜合例項
package com.zjw;
import java.util.ArrayList;
import java.util.List;
/**
* 綜合例項
*/
public class Lambda06
{
public static void main(String[] args) {
List<Dog> list = new ArrayList<>();
list.add(new Dog("aa",1));
list.add(new Dog("aa",5));
list.add(new Dog("aa",3));
list.add(new Dog("aa",4));
list.add(new Dog("aa",2));
//lambda 排序
list.sort((dog1,dog2)->dog2.getAge()-dog1.getAge());
System.out.println(list);
//lambda 遍歷
list.forEach(System.out::println);
//刪除年齡大於3的
list.removeIf(dog -> dog.getAge()>3);
list.forEach(System.out::println);
}
}
6、 @FunctionalInterface註解
package com.zjw;
/**
* @FunctionalInterface註解
*
* 前面我們會發現Consumer介面,Comparator介面都有@FunctionalInterface註解
*
* 這個註解是函式式介面註解,所謂的函式式介面,當然首先是一個介面,然後就是在這個接口裡面只能有一個抽象方法。
* 這種型別的介面也稱為SAM介面,即Single Abstract Method interfaces
*
* 特點
* - 介面有且僅有一個抽象方法
* - 允許定義靜態方法
* - 執行定義預設 方法
* - 允許java.lang.Object中的public方法
* - 該註解不是必須的,如果一個介面符合"函式式介面"定義,那麼加不加該註解都沒有影響。加上該註解能夠更好地讓編譯器進行檢查。如果編寫的不是函式式介面,但是加上了@FunctionalInterface,那麼編譯器會報錯
*/
public class Lambda07
{
public static void main(String[] args) {
}
@FunctionalInterface
interface TestInterface{
//抽象方法
public void sub();
//java.lang.Object中的public方法
public boolean equals(Object var);
//預設方法
default void defaultMethod(){}
//靜態方法
public static void staticMethod(){}
}
}
7、內建函式式介面
Java.util.function,提供四個核心介面
1、功能型介面(Function)
public interface Function<T,R>{public R apply(T t)}
【接收一個引數,返回一個處理結果】
2、消費型介面(Consumer)
public interface Consumer<T>{public void accept(T t)}
【只接收資料,不返回結果】
3、供給型介面(Supplier)
public interface Supplier<T>{public T get()}
【不接收資料,可以返回結果】
4、斷言型介面(Predicate)
public interface Predicate<T>{public boolean test(T t)}
【進行判斷操作使用】
函式式介面——接收引數並且返回一個處理結果
String類有一個方法:
public boolean startsWith(String str)
package com.test;
import java.util.function.Function;
public class Test03 {
public static void main(String[] args) {
Function<String, Boolean> fun = "##123"::startsWith;
System.out.println(fun.apply("#"));
}
}
消費型介面(Consumer)
package com.test;
import java.util.function.Consumer;
class MyDemo
{
public void print(String str)
{
System.out.println(str);
}
}
public class Test03 {
public static void main(String[] args) {
Consumer<String> fun = System.out::println;
fun.accept("Hello World!");;
}
}
供給型介面
package com.test;
import java.util.function.Supplier;
public class Test03 {
public static void main(String[] args) {
Supplier<String> fun = "hello"::toUpperCase;
System.out.println(fun.get());
}
}