Jdk1.8新特性---Lambda表達式優勢(策略模式改進實現)

 

Jdk1.8加入了諸多特性及語法改進,其中Labmda表達式是一個顯著的語法改進,會使語法更加簡潔。下面給兩個例子來彰顯他的優勢,如果第一個例子還不能說服你的話,請看第二個例子。


目錄

匿名內部類

Lambda表達式舉例

舉例一:標準的匿名內部類實現及改進

Jdk1.8以前寫法:

修改爲Lambda表達式寫法:

舉例二:體會這個例子的牛逼之處

 1、最普通實現方法

2、策略模式優化

3、匿名實現類優化

4、Lambda表達式優化


匿名內部類

出現的原因就是不想寫多餘的代碼,不需要定義單獨的實現類,只需要接口。我們可以直接通過實現接口的方式來實現其方法邏輯,因此這個匿名內部類是沒有真正的類名的,所以就沒有顯示的構造方法,只有默認的無參構造方法。

Lambda表達式舉例

舉例一:標準的匿名內部類實現及改進

Jdk1.8以前寫法:

先定義一個接口A,其中有一個get方法待實現

public interface A {
     void get(String param);
}

然後在主函數中去實現它,並將入參打印輸出。可以看到A接口並沒有真正的實現類定義,只是在我們要用到他的時候,new了一下接口轉而實現其方法。

public static void main(String[] args) {
        A a = new A() {
            @Override
            public void get(String param) {
                System.out.println(param);
            }
        };

        String testParam = "test param";
        a.get(testParam);
    }

輸出結果:

修改爲Lambda表達式寫法:

public static void main(String[] args) {
        A a = (param)-> System.out.println(param);// 此處把一坨改爲了一句

        String testParam = "test param";
        a.get(testParam);
    }

 對比前後,jdk1.7的寫法一大坨,其實我們關注的只是那個接口最終的實現而已;而Lambda表達式將那一坨沒有用的東西剔除,簡化爲一行:A a = (param)-> System.out.println(param);當然語句多了要在->後面增加大括號,比如:

public static void main(String[] args) {
        A a = (param) -> {
            System.out.println(param);
        };

        String testParam = "test param";
        a.get(testParam);
    }

舉例二:體會這個例子的牛逼之處

此時某個班級剛進行一場考試,考了語文和數學,共五個同學,成績如下:

  • 小紅:語文98 數學100
  • 小明:語文60 數學99
  • 小王:語文97 數學59
  • 豆豆:語文85 數學79
  • 小李:語文77 數學75

要求:方法1、篩選出語文成績>=85的同學;方法2、篩選出數學成績>=75的同學

此時構建Student類(Get、Set方法略)

public class Student {

    private String studentName;// 學生姓名

    private Integer chineseScore;// 語文成績

    private Integer mathScore;// 數學成績

    public Student(String studentName, Integer chineseScore, Integer mathScore) {
        this.studentName = studentName;
        this.chineseScore = chineseScore;
        this.mathScore = mathScore;
    }

    @Override
    public String toString() {
        return studentName+" "+chineseScore+" "+mathScore;
    }
}

 1、最普通實現方法

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小紅", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================語文成績>=85的同學================");
        System.out.println(getResult1(studentList));
        System.out.println("===================數學成績>=75的同學================");
        System.out.println(getResult2(studentList));
    }

    /**
     * 篩選出語文成績>=85的同學
     */
    public static List<Student> getResult1(List<Student> studentList) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (_student.getChineseScore() >= 85) {
                resultList.add(_student);
            }
        }
        return resultList;
    }

    /**
     * 篩選出數學成績>=75的同學
     */
    public static List<Student> getResult2(List<Student> studentList) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (_student.getMathScore() >= 75) {
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

運行結果:

很顯然上述兩個方法,其實現算法完全一樣,重複造輪子,這裏使用策略模式對其進行優化。

2、策略模式優化

首先定義一個接口,並定義一個get方法,此方法用於實現各自的算法:

public interface Strategy<T> {

    boolean get(T t);
}

然後定義兩個實現類,語文、數學,分別實現該接口及方法

/**
 * 語文
 */
public class ChineseStrategy implements Strategy<Student> {
    @Override
    public boolean get(Student student) {
        return student.getChineseScore()>=85;// 語文成績>=85
    }
}
/**
 * 數學
 */
public class MathStrategy implements Strategy<Student> {

    @Override
    public boolean get(Student student) {
        return student.getMathScore()>=75;// 數學成績>=75
    }
}

然後在最終調用類中,使用for循環寫統一通用方法getResult,並增加入參Strategy,根據在main方法中的入參實現類不同,去調用不同的子類方法(策略模式)。

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小紅", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================語文成績>=85的同學================");
        System.out.println(getResult(studentList,new ChineseStrategy()));
        System.out.println("===================數學成績>=75的同學================");
        System.out.println(getResult(studentList,new MathStrategy()));
    }

    /**
     * 篩選通用方法
     */
    public static List<Student> getResult(List<Student> studentList, Strategy<Student> strategy) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (strategy.get(_student)) {// 策略模式,根據入參實現類的不同 分別調用子類方法
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

上述方法省去了重複寫for循環的問題,但依然感覺寫兩個實現類很麻煩,每個裏面就一個方法一行代碼,囉嗦。好!此處該匿名實現類登場!!!

3、匿名實現類優化

 在main方法中,直接調用兩次匿名實現類實現算法即可!方便!nice!

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小紅", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================語文成績>=85的同學================");
        System.out.println(getResult(studentList, new Strategy<Student>() {
            @Override
            public boolean get(Student student) {
                return student.getChineseScore() >= 85;
            }
        }));
        System.out.println("===================數學成績>=75的同學================");
        System.out.println(getResult(studentList, new Strategy<Student>() {
            @Override
            public boolean get(Student student) {
                return student.getMathScore() >= 75;
            }
        }));
    }

    /**
     * 篩選通用方法
     */
    public static List<Student> getResult(List<Student> studentList, Strategy<Student> strategy) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (strategy.get(_student)) {
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

4、Lambda表達式優化

看到了匿名實現類,那麼 Lambda表達式又可將其簡化!!

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("小紅", 98, 100));
        studentList.add(new Student("小明", 60, 99));
        studentList.add(new Student("小王", 97, 59));
        studentList.add(new Student("豆豆", 85, 79));
        studentList.add(new Student("小李", 77, 75));
        System.out.println("===================語文成績>=85的同學================");
        System.out.println(getResult(studentList, (student -> student.getChineseScore() >= 85)));
        System.out.println("===================數學成績>=75的同學================");
        System.out.println(getResult(studentList, (student -> student.getMathScore() >= 75)));
    }

    /**
     * 篩選通用方法
     */
    public static List<Student> getResult(List<Student> studentList, Strategy<Student> strategy) {
        List<Student> resultList = new ArrayList<>();
        for (Student _student : studentList) {
            if (strategy.get(_student)) {
                resultList.add(_student);
            }
        }
        return resultList;
    }
}

查看運行結果:

來吧!兄弟們!還!有!誰!~ 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章