1. 程式人生 > >java8新特性 (Lambda表示式)

java8新特性 (Lambda表示式)

1:lambda表示式入門

      提供的介面有四種:

                     ->Function<T,R>接受一個引數T,返回一個引數R

                    ->Consumer<T>接受一個引數T,無返回值

                    ->Supplier<T>不接受引數,返回一個引數T

                    ->Predicate<T>接受一個引數T,返回boolean值

程式碼如下:

        /***
         *  ---------------初級入門---------------
         */
        // 01:Function<T,R>函式介面:接受一個引數T,返回一個引數R
        Function<Integer,Integer> function = p -> p * 10;
        System.out.println(function.apply(2));

        // 02:Consumer<T>函式介面:接受一個引數T,沒有返回
        Consumer<String> consumer = p -> System.out.println(p);
        consumer.accept("你好啊,我是lambda表示式");

        // 03:Predicate<T>函式介面:接受一個引數T,返回一個boolean值
        Predicate<Integer> predicate = (a) -> a > 10;
        System.out.println(predicate.test(1));

        // 04:Supplier<T>函式介面:不接受引數,返回一個引數T
        Supplier<Integer> supplier = () -> 100;
        System.out.println(supplier.get());

執行結果:

當然,你還可以自定義函式介面

       1:自定義的函式介面需要用@FunctionalInterface註解

       2:然後自定義一個抽象方法

例:自定義了一個函式介面MyLambda <T,E,R>接受兩個引數T,E,返回一個引數R

自定義的函式介面:

@FunctionalInterface
public interface MyLambda<T,E,R> {

    // 自定義一個函式介面,接受兩個引數T,E,返回引數R
    R num(T t,E e);
}

程式碼:

        // 05:自定義函式介面:需要自定義一個介面,用上@FunctionalInterface註解
        MyLambda<Integer,Integer,Integer> myLambda = (a,b) -> a + b;
        System.out.println(myLambda.num(1,2));

執行結果:

以上,就是Lambda的簡單入門。Lambda的表示式不用我多說了(箭頭左邊是引數,箭頭右邊是方法體)

 

結合集合一起用:

       在網上覆制了一個字元陣列,讓我們來看看怎麼用Lambda表示式迴圈變數字元陣列,然後在和增強for比一下效率

程式碼如下:

        String[] players = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka", "David Ferrer",
                "Roger Federer", "Andy Murray",
                "Tomas Berdych", "Juan Martin Del Potro",
                "Richard Gasquet", "John Isner"};

        long currtenTime = System.currentTimeMillis();
        // 01:給這個陣列排序
        Arrays.sort(players,(p1,p2) -> p1.compareTo(p2));

//        Arrays.asList(players).forEach((p) -> System.out.println(p));
        for(String s : players){
            System.out.println(s);
        }
        long oldTime = System.currentTimeMillis();
        System.out.println("相差時間:" + (oldTime - currtenTime));

檢視結果:

    這是使用增強for的遍歷

  這是使用lambda表示式的遍歷

 

發現效率差不多,就問你們lambda表示式騷不騷,三行增強for的程式碼變成了一句程式碼。爽不爽!匿名內部類的自定義排序也在使用lambda表示式的情況下,變成了一句程式碼,感覺如何?

                                             打上註釋的是lambda表示式

lambda也可以用來代替匿名內部類

程式碼如下:

        // 定義一個字元陣列
        String[] players = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka", "David Ferrer",
                "Roger Federer", "Andy Murray",
                "Tomas Berdych", "Juan Martin Del Potro",
                "Richard Gasquet", "John Isner"};

        // 01:給這個陣列排序,然後遍歷輸出(根據字串的大小)
        Arrays.sort(players,(p1,p2) -> p1.compareTo(p2));
        Arrays.asList(players).forEach((p) -> System.out.println(p));
        System.out.println("-------------------------");

        // 02:根據字串的長度排序\
        Arrays.sort(players,(p1,p2) -> p1.length() - p2.length());
        Arrays.asList(players).forEach((p) -> System.out.println(p));
        System.out.println("-------------------------");

        // 03:根據字串最後一個字元
        Arrays.sort(players,(p1,p2) -> p1.charAt(p1.length() - 1) - p2.charAt(p2.length() - 1));
        Arrays.asList(players).forEach((p) -> System.out.println(p));

是不是感覺簡單明瞭,還略帶有點騷氣。(唯一就是有點不好,可讀性不是很好)

 

lambda表示式整合集合一起使用:

Person類:

public class Person {

    private String firstName, lastName, job, gender;
    private int age;
    private double salary;

    public Person(String firstName, String lastName, String job,
                  String gender, int age, int salary)       {
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.age = age;
        this.job = job;
        this.salary = salary;
    }

程式碼如下:

    給每個人漲薪資20%,用lambda表示式:

        /**
         * 給每個人的薪資漲20%
         *   1:很容易的我們就想到了用Consumer函式介面來接受增長後的薪資(傳入一個引數,沒有返回值)
         *   2:獲取到增長後的薪資後,forEach設定
         *   3:最後forEach獲取
         */
        long currentTime = System.currentTimeMillis();

        Consumer<Person> consumer = p -> p.setSalary(p.getSalary() + (p.getSalary() / 100 * 20));
        javaProgrammers.forEach(consumer);
        javaProgrammers.forEach(p -> System.out.println(p.getFirstName() + "  " + p.getSalary()));

        long nowTime = System.currentTimeMillis();
        System.out.println("相差時間:" + (nowTime - currentTime));

  執行結果:

      

1.8之前的用法:

        long currentTime = System.currentTimeMillis();

//        Consumer<Person> consumer = p -> p.setSalary(p.getSalary() + (p.getSalary() / 100 * 20));
//        javaProgrammers.forEach(consumer);
//        javaProgrammers.forEach(p -> System.out.println(p.getFirstName() + "  " + p.getSalary()));

        for(int i=0; i< javaProgrammers.size(); i++){
            Person person = javaProgrammers.get(i);
            person.setSalary(person.getSalary() + (person.getSalary() / 100 * 20));
            System.out.println(person.getFirstName() + "  " + person.getSalary());
        }

        long nowTime = System.currentTimeMillis();
        System.out.println("相差時間:" + (nowTime - currentTime));

執行結果:

配合Stream一起使用:

        /**
         * 獲取所有的女人
         *     1:很容易的我們就想到了Predicate函式介面來獲取所有的女程式設計師(傳入一個引數,返回boolean值)
         */
        System.out.println("所有的女人:");
        Predicate<Person> female = p -> p.getGender().equals("female");
        javaProgrammers.stream().filter(female).forEach(p -> System.out.println(p.getFirstName() + "  " + p.getGender()));
        System.out.println();

        /**
         * 獲取月薪超過1400的人
         * 1:很容易的我們就想到了Predicate函式介面來獲取所有的女程式設計師(傳入一個引數,返回boolean值)
         */
        System.out.println("所有月薪超過1400的人:");
        Predicate<Person> personPredicate = p -> (p.getSalary() > 1400);
        javaProgrammers.stream().filter(personPredicate).forEach(p -> System.out.println(p.getFirstName() + "  " + p.getSalary()));
        System.out.println();

        /**
         * 獲取月薪超過1400的女人
         */
        System.out.println("月薪超過1400的女人:");
        javaProgrammers.stream().filter(female).filter(personPredicate).forEach(p -> System.out.println(p.getFirstName() + "  " + p.getSalary()));
        System.out.println();

        /**
         *  按著年齡來排序
         */
        System.out.println("按著年齡來排序 ");
        javaProgrammers.stream().sorted((p1,p2) -> (p1.getAge() - p2.getAge())).forEach(p -> System.out.println(p.getFirstName() + "  " +p.getAge()));
        System.out.println();

        /**
         * 獲取年齡最小的三個人
         */
        System.out.println("獲取年齡最小的三個人:");
        javaProgrammers.stream().sorted((p1,p2) -> p1.getAge() - p2.getAge()).limit(3L).forEach(p -> System.out.println(p.getFirstName() + "  " +p.getAge()));
        System.out.println();

        /**
         * 獲取最高的薪資
         */
        System.out.println("獲取最高的薪資:");
        Person person = javaProgrammers.stream().max((p1, p2) -> new Double(p1.getSalary()).intValue() - new Double(p2.getSalary()).intValue()).get();
        System.out.println(person.getFirstName() + "  " + person.getSalary());

執行結果:

執行結果不就截圖完了;

 

由於實習期間接觸的專案用的還是1.7,所以lambda表示式先學到了這吧到時候用到了再總結吧!

 

畢竟貪多嚼不透。