JDK1.8之lambda表示式

騎著蝸牛行天下發表於2020-06-24

JDK1.8之lambda表示式

lambda是一個匿名函式,可以把lambda表示式理解為一段可以傳遞的程式碼(將程式碼像資料一樣傳遞下去)。可以寫出更加簡潔,靈活的程式碼。作為一種更緊湊的程式碼風格,使Java語言的表達能力得到了提升。

Java支援函數語言程式設計,引入lambda表示式,lambda表示式是實現僅有一個抽象方法的介面的簡化實現。

lambda表示式可以完全替代匿名內部類(只有一個抽象方法的情況下),並且沒有匿名內部類這樣繁瑣的表達結構。

在介面中只定義一個抽象方法(可以有普通方法和靜態方法)為後來的lambda表示式做準備的情況下,可以使用註解@FunctionalInterface,這樣IDEA在編譯階段就會自動檢測出介面中是否只有一個抽象方法,及時報錯。

lambda表示式格式

lambda表示式的基礎語法:JDK1.8中引入了一個新的操作符 “->”該操作符稱為箭頭操作符或lambda操作符,箭頭操作符將lambda表示式拆分成兩部分:

左側:lambda表示式的引數列表

右側:lambda表示式中所需執行的功能,即lambda體。

介面實現類類名 物件名=([介面中抽象方法的引數列表]) ->{
//抽象方法實現語句;
};

在lambda表示式所在的作用域中,引數列表中的引數名不能和作用域中的其他變數名衝突

lambda表示式中的引數個數和介面中抽象方法的引數個數對應。

public class Mytest2 {
    public static void main(String[] args) {
        Student1 student1 = new Student1() {
            @Override
            public void show(int a, int b) {
                System.out.println(a + b);
            }
        };
        System.out.println("-----------------------");
        //簡寫程式碼第一步
        Student1 student2 = (int a,int b) -> {
            System.out.println(a + b);
        };
        //簡寫程式碼第二步
        Student1 student3 = ( a, b) -> {
            System.out.println(a + b);
        };
        //簡寫程式碼第三步
        Student1 student4 = ( a, b) -> System.out.println(a + b);
        //如果對於抽象方法的實現邏輯不少於一行,那麼就不能省略大括號
        Student1 student5 = (int a,int b) -> {
            System.out.println(a - b);
            System.out.println(a + b);
        };
    }
}
--------------------------
public interface Student1 {
    public abstract void show(int a,int b);
}
public class Mytest3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("陝西省");
        list.add("渭南市");
        list.add("澄城縣");
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        System.out.println("-----------------------");
        //用lambda表示式代替上面的遍歷
        ArrayList<String> list1 = new ArrayList<>();
        list.add("陝西省");
        list.add("渭南市");
        list.add("澄城縣");
        list.forEach((String s) -> System.out.println(s));
    }
}
public class Mytest {
    public static void main(String[] args) {
        Car car = new Car() {
            @Override
            public String drive(String Brand) {
                return Brand;
            }
        };
        System.out.println("--------------------");
        //簡寫第一步
        Car car1 = (String  Brand) -> {
            return Brand;
        };
        //簡寫第二步
        Car car2 = (String  Brand) -> Brand;
    }
}
----------------------------------
public interface Car {
    public abstract String drive(String Brand);
}

lambda表示式的核心在於:函式式介面

而函式式介面的核心在於:只有一個方法

實際上函式式變成分為以下四種介面:

(1)功能型函式式介面:public interface Function<T, R> R apply(T t);

(2)供給型函式式介面:public interface Supplier T get();

(3)消費性函式式介面:public interface Consumer void accept(T t);

(4)斷言型函式式介面:public interface Predicate boolean test(T t);

函式式介面引數型別返回型別用途
Consumer 消費型介面Tvoid對型別為T的物件應用操作,包含方法:void accept(T,t)
Supplier 供給型介面T返回型別為T的物件,包含方法:T get()
Function<T,R> 函式型介面TR對型別為T的物件應用操作,並返回結果,結果是R型別的物件,包含方法:R apply(T t)
Predicate 斷言型介面Tboolean確定型別為T的物件是否滿足某約束,並返回Boolean值,包含方法:boolean test(T t)
public class Mytest2 {
    public static void main(String[] args) {
        //函式式介面:Consumer
        Consumer<Integer> consumer = new Consumer<Integer>(){
            @Override
            public void accept(Integer a) {
                System.out.println(a);
            }
        };
        Consumer<Integer> consumer1=(a)->System.out.println(a);
        System.out.println("----------------------");
        //函式式介面:Supplier
        Supplier<Integer> supplier = new Supplier<Integer>(){
            @Override
            public Integer get() {
                return null;
            }
        };
        Supplier<Integer> supplier1 = () -> null;
        System.out.println("----------------------");
        //函式式介面:Predicate
        Predicate<String> predicate = new Predicate<String>(){
            @Override
            public Predicate and(Predicate other) {
                return null;
            }

            @Override
            public boolean test(String s) {
                return false;
            }

            @Override
            public Predicate negate() {
                return null;
            }

            @Override
            public Predicate or(Predicate other) {
                return null;
            }
        };
        System.out.println("------------------------");
        //函式式介面:BinaryOperator
        BinaryOperator<Integer> binaryOperator = new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer a, Integer b) {
                return a*b;
            }
        };
        BinaryOperator<Integer> binaryOperator2 = (a, b) -> a*b;
        System.out.println("------------------------");
    }
}

方法引用

(1)當要傳遞給lambda體的操作,已經有實現的方法了,可以使用方法引用。

(2)方法引用可以看作是lambda表示式深層次的表達,換句話說,方法引用就是lambda表示式,也就是函式式介面的一個例項,通過方法的名字來指向一個方法,可以認為是lambda表示式的一個語法。

(3)要求:實現介面的抽象方法的引數列表和返回值型別,必須與方法引用的 方法的引數列表和返回值型別保持一致。

(4)格式:使用操作符 “::” 將類(物件)與方法名分隔開來。

public class Mytest4 {
    public static void main(String[] args) {
        //Comparator 比較器介面
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer a, Integer b) {
                return Integer.compare(a,b);
            }
        };
        System.out.println("----------------------");
        //lambda表示式
        Comparator<Integer> comparator1=(a,b)->Integer.compare(a,b);
        System.out.println("----------------------");
        //方法引用  類名::靜態方法
        Comparator<Integer> comparator2=Integer::compareTo;
    }
}

一個函式式介面,這個介面中要有兩個引數,還要有返回值型別,BiFunction<U,T,R> U是第一個引數,T是第二個引數,R是返回值型別。

public class Mytest2 {
    public static void main(String[] args) {
        //一個函式式介面,這個介面中要有兩個引數,還要有返回值型別
        //BiFunction<U,T,R> U是第一個引數,T是第二個引數,R是返回值型別
        BiFunction<Integer, Double, Teacher> biFunction = new BiFunction<Integer, Double, Teacher>() {
            @Override
            public Teacher apply(Integer integer, Double aDouble) {
                /*Teacher teacher = new Teacher(integer, aDouble);
                return teacher;*/
                return new Teacher(integer,aDouble);
            }
        };
        //第一步簡化 lambda表示式
        BiFunction<Integer,Double,Teacher> biFunction1=(integer,adouble)->new Teacher(integer,adouble);
        //第二步簡化 方法引用    類名::過載方法
        BiFunction<Integer,Double,Teacher> biFunction2=Teacher::new;
    }
}
---------------------------------
public class Teacher {
    public Teacher(){
        System.out.println("空參構造執行了!");
    }
    public Teacher(Integer age,Double salary){
        System.out.println("有參構造執行了!");
    }
}

相關文章