什么是方法引用
方法引用就是通过类名或方法名引用已经存在的方法来简化lambda表达式。
什么时候可以使用方法引用
如果lamdba体中的内容已经有方法实现了,我们就可以使用方法引用。
方法引用的三种语法格式
1.对象::实例方法名
public class testConsumer {
public static void main(String[] args) {
//匿名内部类
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("匿名内部类测试:" + s);
}
};
//lambda表达式
Consumer consumer1 = x -> System.out.println("lambda表达式测试:" + x);
//方法引用
Consumer<String> consumer2 = new testConsumer()::reference1;
consumer.accept("匿名内部类");
consumer1.accept("lambda表达式");
consumer2.accept("方法引用");
}
public void reference1(String name) {
System.out.println("方法引用测试:" + name);
}
}
consumer接口:
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。
2.类::静态方法名.
public class testConsumer {
public static void main(String[] args) {
//匿名内部类
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("匿名内部类测试:" + s);
}
};
//lambda表达式
Consumer consumer1 = x -> System.out.println("lambda表达式测试:" + x);
//方法引用
Consumer<String> consumer2 = new testConsumer()::reference1;
//静态方法引用
Consumer<String> consumer3 = testConsumer::reference2;
consumer.accept("匿名内部类");
consumer1.accept("lambda表达式");
consumer2.accept("方法引用");
consumer3.accept("静态方法引用");
}
public void reference1(String name) {
System.out.println("方法引用测试:" + name);
}
public static void reference2(String name){
System.out.println("方法引用测试:"+name);
}
}
*注意:被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致。
3. 类::实例方法名
public class testConsumer {
private static final String aa = "aa";
private static final String bb = "bb";
public static void main(String[] args) {
//匿名内部类
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("匿名内部类测试:" + s);
}
};
//lambda表达式
Consumer consumer1 = x -> System.out.println("lambda表达式测试:" + x);
//对象::实例方法名 引用
Consumer<String> consumer2 = new testConsumer()::reference1;
//类::静态方法名 引用
Consumer<String> consumer3 = testConsumer::reference2;
//类::实例方法名 引用
BiPredicate<String,String> predicate = new BiPredicate<String, String>() {
@Override
public boolean test(String s1, String s2) {
return s1.equals(s2);
}
};
BiPredicate<testConsumer,String> predicate1 = (x,y) -> x.equal(y);
BiPredicate<testConsumer,String> predicate2 = testConsumer::equal;
consumer.accept("匿名内部类");
consumer1.accept("lambda表达式");
consumer2.accept("对象::方法名引用");
consumer3.accept("类::静态方法名引用");
System.out.println(predicate2.test(new testConsumer(),"bb"));
}
public void reference1(String name) {
System.out.println("方法引用测试:" + name);
}
public static void reference2(String name){
System.out.println("方法引用测试:"+name);
}
public boolean equal(String a){
System.out.println("类::实例方法名引用");
return a.equals(bb);
}
}
BiPredicate接口:
@FunctionalInterface
public interface BiPredicate<T, U> {
boolean test(T t, U u);
}
注意:第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数时,就可以使用这种语法。
二、构造器引用
类::new
匿名内部类及lambda写法:
//构造器引用
Supplier<testConsumer> supplier = new Supplier<testConsumer>() {
@Override
public testConsumer get() {
return new testConsumer();
}
};
Supplier<testConsumer> supplier1 = () -> new testConsumer();
构造器引用写法:
Supplier<testConsumer> supplier2 = testConsumer::new;
Supplier接口:
@FunctionalInterface
public interface Supplier<T> {
T get();
}
三、数组引用
Type::new
匿名内部类及lambda语法
//数组引用
Function<Integer,String[]> function = new Function<Integer, String[]>() {
@Override
public String[] apply(Integer s) {
return new String[s];
}
};
Function<Integer,String[]> fun = x -> new String[x];
数组引用写法:
Function<Integer, String[]> fun = String[]::new;
总结
- 方法应用及构造器引用其实可以理解为lamdba的另一种表现形式
- 方法引用被调用的方法的参数列表和返回值类型需要与函数式接口中抽象方法的参数列表和返回值类型要一致
- 方法引用中使用类::实例方法的条件是第一个参数是这个实例方法的调用者,第二个参数是这个实例方法的参数
- 构造器引用需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表一致