天天看點

JDK8新特性之Lamda表達式1. lambda表達式。2. 函數式接口3.JDK内置的函數式接口

1. lambda表達式。

  • Lambda表達式:特殊的匿名内部類,文法更簡潔。
  • Lambda表達式允許把函數作為一個方法的參數(函數作為方法參數傳遞),将代碼像資料一樣傳遞。
  • 基本文法
    JDK8新特性之Lamda表達式1. lambda表達式。2. 函數式接口3.JDK内置的函數式接口

`` Lambda引入了新的操作符:–>(箭頭操作符),->将表達式分成兩部分

左側: (參數1,參數2...)表示參數清單
           

​ 右側:{}内部是方法體

  • 注意事項
    • 形參清單的資料類型會自動推斷
    • 如果形參清單為空,隻需保留()
    • 如果形參隻有1個,()可以省略,隻需要參數的名稱即可
    • 如果執行語句隻有一句,且無傳回值,{}可以省略,若有傳回值,則若想省去{},則必須同時省略return,且執行語句也保證隻有一句
    • Lambda不會生成一個單獨的内部類檔案

代碼(接口不能執行個體化對象新發現)

public class Lamdb {
    public static void main(String[] args) {
//        Runnable runnable = new Runnable() {//匿名内部類對象
//            @Override
//            public void run() {
//                System.out.println("這裡是使用匿名内部類方法建立線程");
//            }
//        };
//        ===================================================
        //JDK1.8 知道裡面的方法就一個方法。 表達式 ->
        //    (方法的形參)->{方法體} 必須接口中隻有一個抽象方法。
        //    如果方法體中隻有一條語句,那麼可以省略{}
        //     lambda表達式  ///
        //    (壹)  Runnable runnable=()-> System.out.println("這裡是使用lamdb方法建立線程");;
        //(貳)
        Runnable runnable = () -> {
            System.out.println("哈哈,這裡執行多條語句");
            System.out.println("這裡是使用lamdb方法建立線程");
        };
//        Thread thread = new Thread(runnable);
//        thread.start();//啟動線程執行run方法
//        ==================================================
        //最精簡版使用lambda表達式    由 壹知左右等價,将這個類直接當成參數進行使用
        Thread thread = new Thread(() -> System.out.println("這裡是使用lamdb方法建立線程"));
        thread.start();
    }
           

treeset排序詳情看集合架構Java10;treeset中的comparable預設比較String類,比較其它類會報錯!其它實體類需要實作自然比較器Comparable接口!

JDK8新特性之Lamda表達式1. lambda表達式。2. 函數式接口3.JDK内置的函數式接口

lambda例子貳

public class Test01 {
    public static void main(String[] args) {
//  情況壹
//        TreeSet<String> treeSet = new TreeSet<>();//treset中存在排序功能
//        treeSet.add("java02");
//        treeSet.add("java03");
//        treeSet.add("java05");
//        treeSet.add("java01");
//        treeSet.add("java06");
//        treeSet.add("java04");
//        System.out.println(treeSet);
//==========================================================
//   情況貳
//        TreeSet<Person> treeSet = new TreeSet<>();
//        treeSet.add(new Person(1,"張三1"));
//        treeSet.add(new Person(3,"張三3"));
//        treeSet.add(new Person(5,"張三5"));
//        treeSet.add(new Person(2,"張三2"));
//        treeSet.add(new Person(4,"張三4"));
//        System.out.println(treeSet);
//=====================================================================
//        情況叁
//        Comparator<Person> comparator=new Comparator<Person>() {
//            @Override
//            public int compare(Person o1, Person o2) {
//                return o1.getId()-o2.getId();
//            }
//        }; //匿名内部類對象編譯後會産生class檔案
        //lamda表達式編譯後不會産生class檔案

        Comparator<Person> comparator=(Person o1, Person o2)->
        {return o1.getId()-o2.getId();};
       // Comparator<Person> comparator=( o1,  o2)-> o1.getId()-o2.getId();

        TreeSet<Person> treeSet = new TreeSet<>(comparator);
        treeSet.add(new Person(1,"張三1"));
        treeSet.add(new Person(3,"張三3"));
        treeSet.add(new Person(5,"張三5"));
        treeSet.add(new Person(2,"張三2"));
        treeSet.add(new Person(4,"張三4"));
        System.out.println(treeSet);
    }
}//Comparable:自然比較器。要求類必須實作Comparable接口。如果該類沒有實作comparable接口。
/*@Data
@NoArgsConstructor
@AllArgsConstructor//情況貳  解決方案實作Comparable接口
class Person implements Comparable<Person>{
    private Integer id;
    private String name;
    @Override//0:兩個元素相同。  >0表示比新添的元素大往後放(小到大)  <0
    public int compareTo(Person o) {
        System.out.println(this.name+"========="+o.name);
        return -(this.id-o.id);//this表示調用這個方法的對象,o表示傳入的對象
    //return -1/0/1;
    }
}*/
@Data
@NoArgsConstructor
@AllArgsConstructor//情況叁 解決方案實作Comparable接口
class Person {
    private Integer id;
    private String name;
}
           

2. 函數式接口

如果一個接口隻有一個抽象方法,則該接口稱之為函數式接口,函數式接口可以使用Lambda表達式,Lambda表達式會被比對到這個抽象方法上。

@Functionallnterface注解檢測接口是否符合函數式接口 (可以回想@override注解)

public class Test02 {
    public static void main(String[] args) {
        USB upan=new USB() {
            @Override //重寫的方法的檢驗
            public void service() {
                System.out.println("使用upan");
            }//匿名内部類
        };

        useUSB(upan);//調用靜态方法useUSB(upan),該方法調用匿名内部類

        USB shubiao=()->System.out.println("使用滑鼠");//lambda表達式修改函數式接口
        useUSB(shubiao);//形式貳

        useUSB(()->System.out.println("使用鍵盤"));//形式叁,以參數形式傳入進去
    }

    //函數式接口的應用:作為方法的參數。 調用方法時可以使用lamdba表達式。主函數中是執行個體
    public static void useUSB(USB usb){
        usb.service();
    }

}
//函數式接口:接口中隻有一個抽象方法。該接口就是函數式接口。
@FunctionalInterface //檢驗該接口是否為函數式接口
interface USB{
    public void service();//服務

   // void aa();加上會報錯
    //JDK8以後新增的特性。
    default void show(){ }
    static void print(){ }
}
           

3.JDK内置的函數式接口

常見得函數式接口

JDK8新特性之Lamda表達式1. lambda表達式。2. 函數式接口3.JDK内置的函數式接口

(1)消費性函數式接口:重寫方法 void accept(T t)由一個參數,但是沒有傳回值

public class Test03 {
    public static void main(String[] args) {
// 方式壹  最傳統的方式進行操作
//        MyConsumer myConsumer=new MyConsumer();
//        fun(myConsumer,15.5);

//   方式二 匿名内部類方式
//          Consumer<Double> consumer=new Consumer<Double>() {
//              @Override
//              public void accept(Double aDouble) {
//                  System.out.println("你今天洗腳消費:"+aDouble);
//              }
//          };
//          fun(consumer,200.0);

        //方式叁 lambda方式   隻有一個參數可以使用下面的方式傳參
//          Consumer<Double> consumer= aDouble->System.out.println("你今天按摩消費:"+aDouble);
//
//          fun(consumer,300.0);

=================== //供給型函數式接口方式=================================
//           Supplier<String> s1=()->{
//               return "你們今天隻上了2個半小時,怎麼辦!";
//           };
//
//        String s = fun2(s1);
//        System.out.println(s);
=========================//函數型函數式接口=================================
         //R apply(T t);R表示傳回類型,T表示輸入值的類型
        Function<Double,String> f1=t->{
            return "你今天洗腳消費:"+t/10;
        };
        System.out.println(fun3(f1));
    }
    //------------------------------------------------------------------------
   ========================= //消費性函數式接口的使用。======================
    public static void fun(Consumer<Double> consumer,Double param){
         consumer.accept(param);//有形參無傳回值   多态:
    }
   ============================== //供給型函數式接口=========================
    public static String fun2(Supplier<String> supplier){
        return supplier.get();
    }
    ======================//函數型函數式接口=========================
    public static String fun3(Function<Double,String> function){
        return function.apply(200.0);
    }
}
class MyConsumer<Double> implements Consumer<Double>{
    @Override
    public void accept(Double aDouble) {
        System.out.println("我的消費金額:"+aDouble);
    }
}
=============================//斷言型函數=====================================
    //boolean test(T t); 斷言函數式接口 有參傳回值為boolean值
    public static void main(String[] args) {
        Predicate<Integer> predicate=t->{
           boolean value= t>=18?true:false;
           return value;
        };
        System.out.println(fun(predicate,18));
    }
    public static boolean fun(Predicate<Integer> predicate,int age){
        return predicate.test(age);
    }