java8方法引用
Posted yuanbing1226
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8方法引用相关的知识,希望对你有一定的参考价值。
在java中我们可以通过创建新的对象来使用对象的引用
List<String> list = new ArrayList<>();
store(list);
那么对于方法呢,如果我们想在另一个方法中使用对象的方法,那么就必须将对象传递到这个方法中。试想以下,我们把方法的行为当参数传递会不会更好呢。在java8中,lambda表达式可以轻松做到这一点,方法引用的语法是 Object :: methodName。
Consumer<String> c = s -> System.out.println(s);
为了使代码更清晰,可以将lambda表达式转换为方法引用。
Consumer<String> c = System.out :: println;
在方法引用中,将包含该方法的对象(或类)放在::运算符之前,并将该方法的名称放在没有参数的位置之后。首先,方法引用不能用于任何方法。它只能用于替换单个方法的lambda表达式。要使用lambda表达式,首先得有一个
函数接口,即一个只有一个抽象方法的函数接口。
几种类型的方法引用
- 1 对静态方法的方法引用。
- 2 对特定类型对象的示例方法的方法引用。
- 3 对现有对象实例方法的方法引用。
- 4 对构造函数的方法引用。
静态方法的方法引用
(args)-> Class.staticMethod(args);
Class :: staticMethod;
我们用方法引用符号 :: 代替 . ,并且不会将参数传递给方法引用,通常我们不必将参数传递给方法引用。但是参数取决于方法引用的类型。
在这种情况下,该方法采用的任何参数(如果有的话)会自动传递到后面。请看下例
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]
对特定类型对象的示例方法的方法引用
我们有如下lambda表达式
(obj, args) -> obj.instanceMethod(args)
如果一个对象的实例被传递,并且它的一个方法被执行了一些可选的参数,这可以转化为以下方法引用。
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);
}
对现有对象实例方法的方法引用
public class Car {
private String id;
private String color;
}
public void execute(Car car, Consumer<Car> c) {
c.accept(car);
}
execute(car, mechanic::fix);
对构造函数的方法引用
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;
结束语
在编程中使用方法引用,可以优化lambda,这样的代码更加简介,富于表达。上文中引用的代码可以在GitHub上进行下载
以上是关于java8方法引用的主要内容,如果未能解决你的问题,请参考以下文章