什么是Lambda表達(dá)式
Lambda表達(dá)式是Java 8的新特性掷漱,是函數(shù)式接口的實(shí)例。使用Lambda表達(dá)式可以寫(xiě)出更簡(jiǎn)潔、更靈活的代碼。
Lambda表達(dá)式語(yǔ)法
Lambda語(yǔ)法格式:
(parameters) -> expression
// 或
(parameters) -> { statements; }
->
:叫做Lambda操作符
或箭頭操作符
遍坟。
->
左邊:Lambda形參列表(其實(shí)就是借口中的抽象方法的形參列表)
->
右邊:Lambda體(其實(shí)就是重寫(xiě)的抽象方法的方法體)
Lambda表達(dá)式的使用
這里我們將Lambda表達(dá)式的使用細(xì)分為6中情況,下面結(jié)合例子進(jìn)行介紹:
-
情況一:無(wú)參晴股,無(wú)返回值
public class LambdaTest { //語(yǔ)法格式一:無(wú)參愿伴,無(wú)返回值 @Test public void test1() { //普通寫(xiě)法 Runnable r1 = new Runnable() { @Override public void run() { System.out.println("公眾號(hào):程序員汪汪------關(guān)注我"); } }; r1.run(); System.out.println("**************************"); //Lambda表達(dá)式的寫(xiě)法 Runnable r2 = () -> System.out.println("公眾號(hào):程序員汪汪------關(guān)注我"); r2.run(); } }
-
情況二:Lambda表達(dá)式需要一個(gè)參數(shù),但是沒(méi)有返回值队魏。
//語(yǔ)法格式二:Lambda需要一個(gè)參數(shù)公般,但是沒(méi)有返回值 @Test public void test2() { //普通寫(xiě)法 Consumer<String> con = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }; con.accept("公眾號(hào):程序員汪汪------關(guān)注我"); System.out.println("**************************"); //Lambda表達(dá)式的寫(xiě)法 Consumer<String> con1 = (String s) -> {System.out.println(s);}; con1.accept("公眾號(hào):程序員汪汪------關(guān)注我"); }
-
情況三:數(shù)據(jù)類(lèi)型可以省略,因?yàn)榭捎删幾g器推斷得出胡桨,稱(chēng)為
類(lèi)型推斷
//語(yǔ)法格式三:數(shù)據(jù)類(lèi)型可以省略,因?yàn)榭捎删幾g器推斷得出瞬雹,稱(chēng)為“類(lèi)型推斷” @Test public void test3() { Consumer<String> con1 = (String s) -> { System.out.println(s); }; con.accept("公眾號(hào):程序員汪汪------關(guān)注我"); System.out.println("**************************"); //Lambda表達(dá)式的寫(xiě)法 Consumer<String> con1 = (String s) -> {System.out.println(s);}; con1.accept("公眾號(hào):程序員汪汪------關(guān)注我"); }
-
情況四:Lambda表達(dá)式若只需要一個(gè)參數(shù)時(shí)昧谊,參數(shù)的小括號(hào)可以省略
//語(yǔ)法格式四:Lambda 若只需要一個(gè)參數(shù)時(shí),參數(shù)的小括號(hào)可以省略 @Test public void test4() { Consumer<String> con1 = (s) -> { System.out.println(s); }; con1.accept("hhhhh"); System.out.println("***************"); Consumer<String> con2 = s -> { System.out.println(s); }; con2.accept("hhhhhhhhhhhh"); }
注意:無(wú)參數(shù)時(shí)酗捌,小括號(hào)是一定不能省略的呢诬。
-
情況五:Lambda表達(dá)式需要兩個(gè)或兩個(gè)以上的參數(shù)涌哲,有多條執(zhí)行語(yǔ)句,并且可以有返回值
//語(yǔ)法格式五:Lambda表達(dá)式需要兩個(gè)或兩個(gè)以上的參數(shù)尚镰,有多條執(zhí)行語(yǔ)句阀圾,并且可以有返回值 @Test public void test5() { Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { System.out.println(o1); System.out.println(o2); return o1.compareTo(o2); } }; System.out.println(com1.compare(12, 21)); System.out.println("***********************"); Comparator<Integer> com2 = (o1, o2) -> { System.out.println(o1); System.out.println(o2); return o1.compareTo(o2); }; System.out.println(com2.compare(12, 6)); }
-
情況六:當(dāng)Lambda體只有一條語(yǔ)句時(shí),return 與大括號(hào)若有狗唉,都可以省略
//語(yǔ)法格式六:當(dāng) Lambda 體只有一條語(yǔ)句時(shí)初烘,return 與大括號(hào)若有,都可以省略 @Test public void test6() { Comparator<Integer> com1 = (o1, o2) -> { return o1.compareTo(o2); }; System.out.println(com1.compare(12, 6)); System.out.println("****************"); Comparator<Integer> com2 = (o1, o2) -> o1.compareTo(o2); System.out.println(com2.compare(12, 26)); }
總結(jié)
->
左邊:Lambda表達(dá)式的形參列表的參數(shù)類(lèi)型可以省略(類(lèi)型推斷)分俯;如果Lambda形參列表只有一個(gè)參數(shù)肾筐,其一對(duì)()
可以省略,沒(méi)有參數(shù)和有多個(gè)參數(shù)的情況下()
不能省略缸剪。
->
右邊:Lambda體應(yīng)該使用一對(duì){}
包裹吗铐;如果Lambda體只有一條執(zhí)行語(yǔ)句(可能是return語(yǔ)句),其一對(duì){}
可以省略杏节,如果是return語(yǔ)句唬渗,想要省略一對(duì){}
,那么return
關(guān)鍵字也必須省略奋渔;有多條語(yǔ)句時(shí)谣妻,不能省略。
Lambda表達(dá)式的本質(zhì):作為函數(shù)式接口的實(shí)例卒稳。函數(shù)式接口就是只聲明了一個(gè)抽象方法的接口蹋半。
函數(shù)式接口
函數(shù)式接口就是只聲明了一個(gè)抽象方法的接口。
在Java 8中充坑,java.util.function
包下定義了豐富的函數(shù)式接口减江,這些接口上都使用了@FunctionalInterface
注解,這樣可以檢查它是否是一個(gè)函數(shù)式接口捻爷。我們也可以使用該注解定義自己的函數(shù)式接口辈灼。
想要使用Lambda表達(dá)式,那么就一定需要函數(shù)式接口也榄,Lambda就是函數(shù)式接口的實(shí)例巡莹。
java內(nèi)置四大核心函數(shù)式接口
函數(shù)式接口 | 參數(shù)類(lèi)型 | 返回類(lèi)型 | 用途 |
---|---|---|---|
Consumer<T><br />消費(fèi)型接口 | T | void | 對(duì)類(lèi)型為T(mén)的對(duì)象應(yīng)用操作。包含方法:void accept(T t) |
Supplier<T><br />供給型接口 | 無(wú) | T | 返回類(lèi)型為T(mén)的對(duì)象甜紫,包含方法:T get() |
Function<T, R><br />函數(shù)型接口 | T | R | 對(duì)類(lèi)型為T(mén)的對(duì)象應(yīng)用操作降宅,并返回結(jié)果。結(jié)果類(lèi)型是R類(lèi)型的對(duì)象囚霸。方法包含:R apply(T t) |
Predicate<T><br />斷定型接口 | T | boolean | 確定類(lèi)型為T(mén)的對(duì)象是否滿(mǎn)足某約束腰根,并返回boolean值。包含方法:boolean test(T t) |
其他接口
函數(shù)式接口 | 參數(shù)類(lèi)型 | 返回類(lèi)型 | 用途 |
---|---|---|---|
BiFunction<T, U, R> | T, U | R | 對(duì)類(lèi)型為T(mén), U參數(shù)應(yīng)用操作拓型,返回R類(lèi)型的結(jié)果额嘿。包含方法:R apply(T t, U u) |
UnaryOperator<T><br />(Function子接口) | T | T | 對(duì)類(lèi)型為T(mén)的對(duì)象進(jìn)行一元運(yùn)算瘸恼,并返回T類(lèi)型的結(jié)果。包含方法:T apply(T t) |
BinaryOperator<T><br />(BiFunction子接口) | T, T | T | 對(duì)類(lèi)型為T(mén)的對(duì)象進(jìn)行二元運(yùn)算册养,并返回T類(lèi)型的結(jié)果东帅。包含方法:T apply(T t1, T t2) |
BiConsumer<T, U> | T, U | void | 對(duì)類(lèi)型為T(mén), U參數(shù)應(yīng)用操作。包含方法:void accept(T t, U u) |
BiPredicate<T, U> | T, U | boolean | 包含方法:boolean test(T t, U u) |
ToIntFunction<T><br />ToLongFunction<T><br />ToDoubleFunction<T> | T | int<br />long<br />double | 分別計(jì)算int球拦、long靠闭、double值得函數(shù) |
IntFunction<R><br />LongFunction<R><br />DoubleFunction<R> | int<br />long<br />double | R | 參數(shù)分別為int、long刘莹、double類(lèi)型的函數(shù) |
Java提供的函數(shù)式接口還有很多阎毅,上表只列舉了一部分函數(shù)式接口,在以后的開(kāi)發(fā)中可能會(huì)遇到点弯。凡是開(kāi)發(fā)中遇到了函數(shù)式接口扇调,都可以運(yùn)用Lambda表達(dá)式。
函數(shù)式接口的基本命名準(zhǔn)則
Java提供的函數(shù)式接口遵循以下基本命名準(zhǔn)則:
- 如果只處理對(duì)象而非基本類(lèi)型抢肛,名稱(chēng)則為
Function
狼钮,Consumer
,Predicate
等捡絮。參數(shù)類(lèi)型通過(guò)泛型添加熬芜。 - 如果接收的參數(shù)是基本類(lèi)型,則由名稱(chēng)的第一部分表示福稳,如
LongConsumer
涎拉,DoubleFunction
,IntPredicate
等的圆,但返回基本類(lèi)型的Supplier
接口例外鼓拧。 - 如果返回值為基本類(lèi)型,則用
To
表示越妈,如ToLongFunction <T>
和IntToLongFunction
季俩。 - 如果返回值類(lèi)型與參數(shù)類(lèi)型相同,則是一個(gè)
Operator
:?jiǎn)蝹€(gè)參數(shù)使用UnaryOperator
梅掠,兩個(gè)參數(shù)使用BinaryOperator
酌住。 - 如果接收參數(shù)并返回一個(gè)布爾值,則是一個(gè) 斷言 (
Predicate
)阎抒。 - 如果接收的兩個(gè)參數(shù)類(lèi)型不同酪我,則名稱(chēng)中有一個(gè)
Bi
。
這里使用java內(nèi)置的四大核心函數(shù)式接口舉兩個(gè)例子:
public class LambdaTest2 {
//消費(fèi)型接口Consumer
public void happyTime(double money, Consumer<Double> consumer) {
consumer.accept(money);
}
@Test
public void test() {
happyTime(500, new Consumer<Double>() {
@Override
public void accept(Double aDouble) {
System.out.println("學(xué)習(xí)好累啊挠蛉,出去嗨一下祭示,花了" + aDouble + "元");
}
});
System.out.println("******************************");
happyTime(400, money -> {
System.out.println("學(xué)習(xí)好累啊,出去嗨一下谴古,花了" + money + "元");
});
}
//根據(jù)給定的規(guī)則质涛,過(guò)濾集合中的字符串。此規(guī)則由Predicate的方法決定
public List<String> filterString(List<String> list, Predicate<String> predicate) {
ArrayList<String> filterList = new ArrayList<>();
for (String s : list) {
if (predicate.test(s)) {
filterList.add(s);
}
}
return filterList;
}
//斷定型接口 Predicate
@Test
public void test2(){
List<String> list = Arrays.asList("北京", "南京", "天津", "東京", "西京", "普京");
//普通寫(xiě)法
List<String> filterList = filterString(list, new Predicate<String>() {
@Override
public boolean test(String s) {
return s.contains("京");
}
});
System.out.println(filterList);
System.out.println("******************************");
//Lambda表達(dá)式寫(xiě)法
List<String> filterList2 = filterString(list, s -> s.contains("京"));
System.out.println(filterList2);
}
}
/**
test1 運(yùn)行結(jié)果:
學(xué)習(xí)好累啊掰担,出去嗨一下汇陆,花了500.0元
******************************
學(xué)習(xí)好累啊,出去嗨一下带饱,花了400.0元
test2 運(yùn)行結(jié)果:
[北京, 南京, 東京, 西京, 普京]
******************************
[北京, 南京, 東京, 西京, 普京]
*/
方法引用
方法引用本質(zhì)上就是Lambda表達(dá)式毡代,而Lambda是函數(shù)式接口的實(shí)例,所以方法引用也是函數(shù)式接口的實(shí)例
使用情境:當(dāng)要傳遞給Lambda體的操作勺疼,已經(jīng)有實(shí)現(xiàn)的方法了教寂,可以使用方法引用。
方法引用的格式:
類(lèi)(或?qū)ο螅?:: 方法名
具體可以分為如下的三種情況:
- 對(duì)象 :: 非靜態(tài)方法
- 類(lèi) :: 靜態(tài)方法
- 類(lèi) :: 非靜態(tài)方法
案例
Employee工具類(lèi):
public class Employee {
private int id;
private String name;
private int age;
private double salary;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Employee() {
}
public Employee(int id) {
this.id = id;
}
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
public Employee(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", salary=" + salary + '}';
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Employee employee = (Employee) o;
if (id != employee.id)
return false;
if (age != employee.age)
return false;
if (Double.compare(employee.salary, salary) != 0)
return false;
return name != null ? name.equals(employee.name) : employee.name == null;
}
@Override
public int hashCode() {
int result;
long temp;
result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + age;
temp = Double.doubleToLongBits(salary);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}
測(cè)試類(lèi):
public class MethodRefTest {
// 情況一:對(duì)象 :: 實(shí)例方法
//Consumer中的void accept(T t)
//PrintStream中的void println(T t)
@Test
public void test1() {
//普通寫(xiě)法
Consumer<String> con = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
con.accept("hello!");
System.out.println("*****************************");
//Lambda表達(dá)式寫(xiě)法
Consumer<String> con1 = str -> System.out.println(str);
con1.accept("北京");
System.out.println("*****************************");
//方法引用的寫(xiě)法
PrintStream ps = System.out;
Consumer<String> con2 = ps::println;
con2.accept("天安門(mén)");
/**
test1 運(yùn)行結(jié)果:
hello!
*****************************
北京
*****************************
天安門(mén)
*/
}
//Supplier中的T get()
//Employee中的String getName()
@Test
public void test2() {
//普通寫(xiě)法
Employee emp = new Employee(1001, "Tom", 20, 5000);
Supplier<String> sup = new Supplier<String>() {
@Override
public String get() {
return emp.getName();
}
};
System.out.println(sup.get());
System.out.println("***************************************");
//Lambda表達(dá)式寫(xiě)法执庐,emp對(duì)象不變
Supplier<String> sup1 = () -> emp.getName();
System.out.println(sup1.get());
System.out.println("***************************************");
//方法引用的寫(xiě)法
Supplier<String> sup2 = emp::getName;
System.out.println(sup2.get());
/**
test2 運(yùn)行結(jié)果:
Tom
***************************************
Tom
***************************************
Tom
*/
}
// 情況二:類(lèi) :: 靜態(tài)方法
//Comparator中的int compare(T t1,T t2)
//Integer中的int compare(T t1,T t2)
@Test
public void test3() {
//普通寫(xiě)法
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
System.out.println(com.compare(12, 20));
System.out.println("***************************************");
//Lambda 表達(dá)式的寫(xiě)法
Comparator<Integer> com1 = (o1, o2) -> Integer.compare(o1, o2);
System.out.println(com1.compare(12, 20));
System.out.println("***************************************");
//方法引用
Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(12, 20));
/**
test3 運(yùn)行結(jié)果:
-1
***************************************
-1
***************************************
-1
*/
}
//Function中的R apply(T t)
//Math中的Long round(Double d)
@Test
public void test4() {
//普通寫(xiě)法
Function<Double, Long> fun = new Function<Double, Long>() {
@Override
public Long apply(Double aDouble) {
return Math.round(aDouble);
}
};
System.out.println(fun.apply(12.3));
System.out.println("***************************************");
//Lambda表達(dá)式寫(xiě)法
Function<Double, Long> fun1 = (aDouble) -> Math.round(aDouble);
System.out.println(fun1.apply(12.6));
System.out.println("***************************************");
//方法引用的寫(xiě)法
Function<Double, Long> fun2 = Math::round;
System.out.println(fun2.apply(12.5));
/**
test4 運(yùn)行結(jié)果:
12
***************************************
13
***************************************
13
*/
}
// 情況三:類(lèi) :: 實(shí)例方法
// Comparator中的int compare(T t1,T t2)
// String中的int t1.compareTo(t2)
@Test
public void test5() {
//普通方法
Comparator<String> com = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
System.out.println(com.compare("abc", "abe"));
System.out.println("***************************************");
//Lambda 表達(dá)式的方式
Comparator<String> com1 = (o1, o2) -> o1.compareTo(o2);
System.out.println(com1.compare("abc", "abe"));
System.out.println("***************************************");
//方法引用的方式
Comparator<String> com2 = String::compareTo;
System.out.println(com2.compare("abc", "abe"));
/**
test5 運(yùn)行結(jié)果:
-2
***************************************
-2
***************************************
-2
*/
}
//BiPredicate中的boolean test(T t1, T t2);
//String中的boolean t1.equals(t2)
@Test
public void test6() {
//普通寫(xiě)法
BiPredicate<String, String> bip = new BiPredicate<String, String>() {
@Override
public boolean test(String s, String s2) {
return s.equals(s2);
}
};
System.out.println(bip.test("abc", "abd"));
System.out.println("***************************************");
//Lambda表達(dá)式寫(xiě)法
BiPredicate<String, String> bip1 = (s1, s2) -> s1.equals(s2);
System.out.println(bip1.test("abc", "abc"));
System.out.println("***************************************");
//方法引用
BiPredicate<String, String> bip2 = String::equals;
System.out.println(bip2.test("abc", "abc"));
/**
test6 運(yùn)行結(jié)果:
false
***************************************
true
***************************************
true
*/
}
// Function中的R apply(T t)
// Employee中的String getName();
@Test
public void test7() {
//普通寫(xiě)法
Employee emp = new Employee(1001, "Tom", 20, 5000);
Function<Employee, String> func = new Function<Employee, String>() {
@Override
public String apply(Employee employee) {
return employee.getName();
}
};
System.out.println(func.apply(emp));
System.out.println("***************************************");
//Lambda 表達(dá)式的寫(xiě)法 emp不變
Function<Employee, String> func1 = employee -> employee.getName();
System.out.println(func1.apply(emp));
System.out.println("***************************************");
//方法引用寫(xiě)法
Function<Employee, String> func2 = Employee::getName;
System.out.println(func2.apply(emp));
/**
test7 運(yùn)行結(jié)果:
Tom
***************************************
Tom
***************************************
Tom
*/
}
}
方法引用使用的要求:要求接口中的抽象方法的形參列表和返回值類(lèi)型與方法引用的方法的形參列表和返回值類(lèi)型相同酪耕,如果是成員方法(非靜態(tài)方法),會(huì)在方法的參數(shù)列表的第一個(gè)位置增加this
的類(lèi)型轨淌。
分析
首先我們來(lái)分析一下test1的例子ps::println
迂烁,在本例中,實(shí)際上調(diào)用的是void println(String str)
递鹉,它是非靜態(tài)方法盟步,也就是成員方法,按照上述的要求躏结,需要在參數(shù)列表的第一個(gè)位置補(bǔ)上this
也就是PrintStream
却盘,參數(shù)列表就變成了這樣void println(PrintStream ps String str)
,但是因?yàn)?code>::前是一個(gè)PrintStream
實(shí)例ps
媳拴,因此黄橘,方法引用的第一個(gè)參數(shù)this
被綁定給了ps
,所以最終的參數(shù)列表又變回了void println(String str)
禀挫,所以就符合了要求中所說(shuō)的參數(shù)列表和返回值類(lèi)型都與方法引用的方法的形參列表和返回值類(lèi)型相同的要求旬陡,那么就和Consumer<T>
接口的抽象方法void accept(T t)
的返回值和參數(shù)列表一致了,所以就可以使用方法引用语婴。
再來(lái)看test3的例子描孟,test3是情況2的例子,調(diào)用的是靜態(tài)方法砰左,靜態(tài)方法沒(méi)有this
匿醒,所以只要滿(mǎn)足參數(shù)列表和返回值相同的條件就可以使用方法引用。
最后看test5的例子String::compareTo
缠导,在這個(gè)例子中廉羔,int compareTo(String str)
是一個(gè)成員方法(非靜態(tài)方法),按照上述的方法引用使用的要求僻造,需要在參數(shù)列表的第一個(gè)位置上補(bǔ)上this
(在這里憋他,this
的類(lèi)型就是String
)孩饼,為什么是String?因?yàn)?code>compareTo是String
類(lèi)的成員方法竹挡,this
當(dāng)然就是指的是String
镀娶。添加this
后,新的參數(shù)列表就變成了int compareTo(String s, String str)
揪罕,此時(shí)就符合Comparator
接口中的int compare(T t1,T t2)
的要求梯码,所以方法引用就能夠使用了。
總結(jié)
- 成員方法(非靜態(tài)方法)的參數(shù)列表好啰,前面會(huì)追加
this
的類(lèi)型轩娶。 - 靜態(tài)方法因?yàn)闆](méi)有
this
,所以參數(shù)列表不會(huì)追加任何東西 - 當(dāng)
::
前是一個(gè)實(shí)例時(shí)框往,本應(yīng)追加到參數(shù)列表中的this
會(huì)綁定給這個(gè)實(shí)例鳄抒。
構(gòu)造器引用與數(shù)組引用
構(gòu)造器引用:構(gòu)造器引用和方法引用類(lèi)似,函數(shù)式接口的抽象方法的形參列表和構(gòu)造器的形參列表一致搅窿,抽象方法的返回值類(lèi)型即為構(gòu)造器所屬的類(lèi)的類(lèi)型嘁酿。
數(shù)組引用:把數(shù)組看成是一個(gè)特殊的類(lèi),則寫(xiě)法就與構(gòu)造器引用一致了男应。
案例:
案例中仍需使用上面的Employee工具類(lèi)闹司。
public class ConstructorRefTest {
//構(gòu)造器引用
//Supplier中的T get()
@Test
public void test1(){
//普通寫(xiě)法
Supplier<Employee> sup = new Supplier<Employee>() {
@Override
public Employee get() {
return new Employee();
}
};
System.out.println(sup.get());
System.out.println("***************************************");
//Lambda 表達(dá)式寫(xiě)法
Supplier<Employee> sup1 = () -> new Employee();
System.out.println(sup1.get());
System.out.println("***************************************");
//構(gòu)造器引用寫(xiě)法
Supplier<Employee> sup2 = Employee::new;
System.out.println(sup2.get());
/**
運(yùn)行結(jié)果:
Employee{id=0, name='null', age=0, salary=0.0}
***************************************
Employee{id=0, name='null', age=0, salary=0.0}
***************************************
Employee{id=0, name='null', age=0, salary=0.0}
*/
}
//Function中的R apply(T t)
@Test
public void test2(){
//普通寫(xiě)法
Function<Integer, Employee> func = new Function<Integer, Employee>() {
@Override
public Employee apply(Integer id) {
return new Employee(id);
}
};
System.out.println(func.apply(1001));
System.out.println("***************************************");
// Lambda
Function<Integer, Employee> func1 = id -> new Employee(id);
System.out.println(func1.apply(1002));
System.out.println("***************************************");
//構(gòu)造器引用
Function<Integer, Employee> func2 = Employee::new;
System.out.println(func2.apply(1003));
/**
運(yùn)行結(jié)果:
Employee{id=1001, name='null', age=0, salary=0.0}
***************************************
Employee{id=1002, name='null', age=0, salary=0.0}
***************************************
Employee{id=1003, name='null', age=0, salary=0.0}
*/
}
//BiFunction中的R apply(T t,U u)
@Test
public void test3(){
//普通寫(xiě)法
BiFunction<Integer, String, Employee> func = new BiFunction<Integer, String, Employee>() {
@Override
public Employee apply(Integer id, String name) {
return new Employee(id, name);
}
};
System.out.println(func.apply(1001, "Tom"));
System.out.println("***************************************");
//Lambda
BiFunction<Integer, String, Employee> func1 = (id, name) -> new Employee(id, name);
System.out.println(func1.apply(1002, "Jerry"));
System.out.println("***************************************");
//構(gòu)造器引用
BiFunction<Integer, String, Employee> func2 = Employee::new;
System.out.println(func2.apply(1003, "Jack"));
/**
運(yùn)行結(jié)果:
Employee{id=1001, name='Tom', age=0, salary=0.0}
***************************************
Employee{id=1002, name='Jerry', age=0, salary=0.0}
***************************************
Employee{id=1003, name='Jack', age=0, salary=0.0}
*/
}
//數(shù)組引用
//Function中的R apply(T t)
@Test
public void test4(){
//普通寫(xiě)法 Integer代表數(shù)組長(zhǎng)度
Function<Integer, String[]> func1 = new Function<Integer, String[]>() {
@Override
public String[] apply(Integer length) {
return new String[length];
}
};
String[] arr1 = func1.apply(5);
System.out.println(Arrays.toString(arr1));
System.out.println("***************************************");
//Lambda
Function<Integer, String[]> func2 = length -> new String[length];
String[] arr2 = func2.apply(8);
System.out.println(Arrays.toString(arr2));
System.out.println("***************************************");
//數(shù)組引用
Function<Integer, String[]> func3 = String[]::new;
String[] arr3 = func3.apply(10);
System.out.println(Arrays.toString(arr3));
/**
運(yùn)行結(jié)果:
[null, null, null, null, null]
***************************************
[null, null, null, null, null, null, null, null]
***************************************
[null, null, null, null, null, null, null, null, null, null]
*/
}
}
結(jié)語(yǔ):
Lambda表達(dá)式,還是需要多練多寫(xiě)沐飘,如果實(shí)在不會(huì)寫(xiě)游桩,可以使用IDEA的提示功能,在可以使用Lambda表達(dá)式的地方耐朴,可以通過(guò)提示借卧,自動(dòng)轉(zhuǎn)換成Lambda表達(dá)式。建議還是自己多寫(xiě)多練筛峭。