Jdk1.8加入了諸多特性及語法改進,其中Labmda表達式是一個顯著的語法改進,會使語法更加簡潔。下面給兩個例子來彰顯他的優勢,如果第一個例子還不能說服你的話,請看第二個例子。
目錄
匿名內部類
出現的原因就是不想寫多餘的代碼,不需要定義單獨的實現類,只需要接口。我們可以直接通過實現接口的方式來實現其方法邏輯,因此這個匿名內部類是沒有真正的類名的,所以就沒有顯示的構造方法,只有默認的無參構造方法。
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;
}
}
查看運行結果:
來吧!兄弟們!還!有!誰!~