Let's learn java 8 (1) - there is a simple example of functional programming in functional programming:
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"); } }
Where Person::sayHello is called method reference, which can be replaced by Lambda expression. The code is as follows:
public static void main(String[] args) { work((name) -> { System.out.println("hello " + name); }); // hello Jim }
Method references and Lambda relationships
What is the relationship between method references and Lambda expressions?
Method references can be seen as a shortcut to Lambda expressions. This shortcut is based on certain conditions and can be roughly divided into three categories:
- Static method reference
- Self type method reference
- Existing instance method references
Static method reference
The above example is a static method reference. We can use other static methods instead.
public static void main(String[] args) { work(String::toString); work(String::toLowerCase); }
As you can see, a Lambda expression has a parameter (String name). String.toString, String.toLowerCase and Person.sayHello are the same parameter types. As long as the parameter signature is consistent, they can be replaced.
Self type method reference
This can be used when the method body of a Lambda expression directly uses the object method in the parameter. For example:
public static void main(String[] args) { // Mode 1, using Lambda expressions print("hello", (String s) -> s.toLowerCase()); // Method 2, use method reference print("hello", String::toLowerCase); } private static void print(String argu, Consumer<String> consumer) { consumer.accept(argu); }
There is a parameter (String s) in the lambda expression that directly uses the method s.toLowerCase() in the parameter object in the method body, so it can be abbreviated as: String::toLowerCase
In an example of a complex point:
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("Commodity price:" + price); } } public class TestPerson2 { public static void main(String[] args) { Goods goodsApple = new Goods(); goodsApple.setPrice(100); GoodsService service = new GoodsService(goodsApple); // Mode 1, using Lambda expressions service.showPrice((Goods goods) -> { return goods.getPrice(); }); // Method 2, use method reference service.showPrice(Goods::getPrice); } }
There is a Lambda expression in method 1. The parameter is Goods goods, and the getPrice of goods object is called directly in the method body. Therefore, it can be simplified as: service.showPrice(Goods::getPrice).
Existing instance method references
When the object method in the parameter is not used in the method body of Lambda expression, other object methods are used. Here's an example
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); // Mode 1, using Lambda expressions print("Tom", (String s) -> dog.say(s)); // Mode 2, instance object method reference print("Tom", dog::say); } private static void print(String argu, Consumer<String> consumer) { consumer.accept(argu); } }
The second one is different from the third one in that whether the method in the Lambda method body directly uses the method in the Lambda parameter.
Here is a summary of the equivalence between Lambda expressions and method references:
- (dog dog) - > dog. Getage() is equivalent to Dog::getAge
- () - > xxclass. Run() is equivalent to XXClass::run
- (dog, name) - > dog.say (name) is equivalent to Dog::say
- (name) - > dog.say (name) is equivalent to dog::say
Summary
This article mainly introduces method references, and demonstrates three different method references.
Regularly share technology dry goods, learn together and make progress together!