在一塊兒來學Java8(一)——函數式編程
中有一個簡單的函數式編程的例子:java
import java.util.function.Consumer; class Person { public static void sayHello(String name) { System.out.println("hello " + name); } } public class TestPerson { public static void main(String[] args) { work(Person::sayHello); // hello Jim } public static void work(Consumer<String> consumer) { consumer.accept("Jim"); } }
其中Person::sayHello
被稱爲方法引用
,方法引用能夠用Lambda表達式來代替,代碼以下:編程
public static void main(String[] args) { work((name) -> { System.out.println("hello " + name); }); // hello Jim }
方法引用和Lambda表達式之間有什麼關係呢?app
方法引用能夠看作是Lambda表達式的一種快捷方式。這種快捷方式是創建在某種條件之上的,大體能夠分爲三類:函數式編程
上面提到的例子就是靜態方法引用,咱們還能夠使用其它靜態方法來替代函數
public static void main(String[] args) { work(String::toString); work(String::toLowerCase); }
能夠看到,Lambda表達式有一個參數(String name)
,String.toString和String.toLowerCase和Person.sayHello也是一樣的參數類型, 只要是參數簽名一致均可以替換使用。學習
當Lambda表達式的方法體內直接使用參數中的對象方法,能夠使用這種方式。好比下面這個例子:this
public static void main(String[] args) { // 方式1,使用Lambda表達式 print("hello", (String s) -> s.toLowerCase()); // 方式2,使用方法引用 print("hello", String::toLowerCase); } private static void print(String argu, Consumer<String> consumer) { consumer.accept(argu); }
Lambada表達式中有個參數(String s)
在方法體中直接使用了參數對象中的方法 s.toLowerCase()
,所以能夠簡寫爲:String::toLowerCase
code
在來一個複雜點的例子:對象
package learn.java8.ch3; import java.util.function.Function; class Goods { private int price; public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } } class GoodsService { private Goods goods; public GoodsService(Goods goods) { super(); this.goods = goods; } public void showPrice(Function<Goods, Integer> fun) { int price = fun.apply(goods); System.out.println("商品價格:" + price); } } public class TestPerson2 { public static void main(String[] args) { Goods goodsApple = new Goods(); goodsApple.setPrice(100); GoodsService service = new GoodsService(goodsApple); // 方式1,使用Lambda表達式 service.showPrice((Goods goods) -> { return goods.getPrice(); }); // 方式2,使用方法引用 service.showPrice(Goods::getPrice); } }
方式1中有個Lambda表達式,參數爲Goods goods
,在方法體中又直接調用了goods對象的getPrice,所以能夠簡化爲:service.showPrice(Goods::getPrice);
get
當Lambda表達式的方法體內沒有使用參數中的對象方法,使用了其它對象的方法。好比下面這個例子
package learn.java8.ch3; import java.util.function.Consumer; class Dog { private int age; public Dog(int age) { super(); this.age = age; } public void say(String name) { System.out.println("dog age is " + age + ", dog name is " + name); } } public class TestPerson4 { public static void main(String[] args) { Dog dog = new Dog(3); // 方式1,使用Lambda表達式 print("Tom", (String s) -> dog.say(s)); // 方式2,實例對象方法引用 print("Tom", dog::say); } private static void print(String argu, Consumer<String> consumer) { consumer.accept(argu); } }
第二種跟第三種的區別就是,Lambda方法體中有沒有直接使用Lambda參數中的方法。
下面總結一下Lambda表達式和方法引用的等價關係:
本篇主要介紹了方法引用,並分別演示了三種不一樣的方法引用。
按期分享技術乾貨,一塊兒學習,一塊兒進步!