In java we can use object reference by creating new object
List<String> list = new ArrayList<>();
store(list);
So what about the method, if we want to use the method of the object in another method, then we have to pass the object into this method. Consider the following, would it be better for us to pass the behavior of the method as a parameter. In java8, lambda expressions can do this easily, the syntax for method reference is Object::methodName.
Consumer<String> c = s -> System.out.println(s);
为了使代码更清晰,可以将lambda表达式转换为方法引用。
Consumer<String> c = System.out :: println;
In a method reference, place the object (or class) containing the method before the :: operator and after the name of the method where it has no parameters. First, method references cannot be used in any method. It can only be used to replace a lambda expression for a single method. To use a lambda expression, you must first have a
functional interface, that is, a functional interface with only one abstract method.
Several types of method references
- 1 A method reference to a static method.
- 2 A method reference to an example method of an object of a particular type.
- 3 A method reference to an existing object instance method.
- 4 Method references to constructors.
Method reference for static method
(args)-> Class.staticMethod(args);
Class :: staticMethod;
We use the method reference notation :: instead of . , and don't pass parameters to method references, normally we don't have to pass parameters to method references. But the parameters depend on the type of the method reference.
In this case, any arguments the method takes (if any) are automatically passed to the back. Please see the example below
public static boolean isMoreThanFifty(int n1, int n2) {
return (n1 + n2) > 50;
}
public static List<Integer> findNumbers(List<Integer> l, BiPredicate<Integer, Integer> p) {
return l.stream()
.filter(i -> p.test(i, i + 10))
.collect(Collectors.toList());
}
/*
* 使用匿名内部类实现
*/
String s1 = findNumbers(list, new BiPredicate<Integer, Integer>() {
@Override
public boolean test(Integer t, Integer u) {
return (t + u) > 50;
}
}).toString();
System.out.println("s1 : " + s1);
/**
* 使用lambda表达式
*/
String s2 = findNumbers(list, (i1, i2) -> Numbers.isMoreThanFifty(i1, i2)).toString();
System.out.println("s2 : " + s2);
/**
* 使用方法引用
*/
String s3 = findNumbers(list, Numbers :: isMoreThanFifty).toString();
System.out.println("s3 : " + s3);
//console log
s1 : [45, 33, 24, 40]
s2 : [45, 33, 24, 40]
s3 : [45, 33, 24, 40]
a method reference to an example method of an object of a particular type
We have the following lambda expression
(obj, args) -> obj.instanceMethod(args)
If an instance of an object is passed and one of its methods is executed with some optional parameters, this can be translated into the following method reference.
ObjectType::instanceMethod
public double calculateWeight() {
double weight = 0;
// Calculate weight
return weight;
}
public void test() {
List<Shipment> l = new ArrayList<Shipment>();
// Using an anonymous class
calculateOnShipments(l, new Function<Shipment, Double>() {
public Double apply(Shipment s) { // The object
return s.calculateWeight(); // The method
}
});
// Using a lambda expression
calculateOnShipments(l, s -> s.calculateWeight());
// Using a method reference
calculateOnShipments(l, Shipment::calculateWeight);
}
a method reference to an existing object instance method
public class Car {
private String id;
private String color;
}
public void execute(Car car, Consumer<Car> c) {
c.accept(car);
}
execute(car, mechanic::fix);
method reference to constructor
Supplier<List<String>> supplier = new Supplier<List<String>>() {
@Override
public List<String> get() {
return new ArrayList<String>();
}
};
Supplier<List<String>> supplier2 = () -> new ArrayList<String>();
Supplier<List<String>> supplier3 = ArrayList::new;
/*
* 如果构造函数有一个参数,可以使用Function接口。构造函数是两个参数的,可以使用BiFunction,如果是三个参数的话,则不得不创建以自己的函数接口了。
*/
Function<String, Integer> function = Integer::new;
BiFunction<String, String, Locale> biFunction = new BiFunction<String, String, Locale>() {
@Override
public Locale apply(String t, String u) {
return new Locale(u, t);
}
};
biFunction = (lang, country) -> new Locale(lang, country);
biFunction = Locale::new;
concluding remarks
Using method references in programming, lambdas can be optimized, and the code is more concise and expressive. The code referenced above can be downloaded on GitHub
java8 method reference
why the perfect lambda expression is only one line
java8 functional programming