- Lambda表达式写法: s -> System.out.println(s);
- 方法引用写法: System.out::println
一、四种方法引用类型
类型 | 示例 |
引用静态方法 | ContainingClass::staticMethodName |
引用某个对象的实例方法 | containingObject::instanceMethodName |
引用某个类型的任意对象的实例方法 | ContainingType::methodName |
引用构造方法 | ClassName::new |
1、静态方法引用
1 静态方法引用
组成语法格式:ClassName::staticMethodName
@Test
public void test03() {
/*
Integer.compare中方法参数是两个,返回值是一个int,跟函数式接口中的COmparator中的参数列表和返回值类型相同
*/
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
Comparator<Integer> com2 = Integer::compareTo;
}
2 实例对象的方法引用
这种语法与用于静态方法的语法类似,只不过这里使用对象引用而不是类名。实例方法引用又分以下三种类型:
a.实例上的实例方法引用
组成语法格式:instanceReference::methodName
b.超类上的实例方法引用
组成语法格式:super::methodName
方法的名称由methodName指定,通过使用super,可以引用方法的超类版本。还可以捕获this 指针,this :: equals 等价 于lambda表达式 x -> this.equals(x);
public class Man extends Human {
@Override
public void sayHello() {
System.out.println("大家好,我是Man!");
}
//定义方法method,参数传递Greetable接口
public void method(Greetable g){
g.greet();
}
public void show(){
//调用method方法,使用Lambda表达式
method(()‐>{
//创建Human对象,调用sayHello方法
new Human().sayHello();
});
//简化Lambda
method(()‐>new Human().sayHello());
//使用super关键字代替父类对象
method(()‐>super.sayHello());
}
}
c 通过this引用成员方法
组成语法格式:this::methodName
this代表当前对象,如果需要引用的方法就是当前类中的成员方法,那么可以使用“this::成员方法”的格式来使用方
法引用
public class Husband {
private void buyHouse() {
System.out.println("买套房子");
}
private void marry(Richable lambda) {
lambda.buy();
}
public void beHappy() {
marry(this::buyHouse);
}
public static void main(String[] args) {
Husband b = new Husband();
b.beHappy();
}
}
@FunctionalInterface
interface Richable {
void buy();
}
3 引用某个类型的任意对象的实例方法
组成语法格式:ClassName::methodName
这个指向任意类型实例方法的方法引用有两个要求:
第一点:接口方法(四大接口以及其他函数式接口)的参数比引用方法(实际的方法,比如这个类的具体方法)的参数多一个
第二点:接口方法的第一个参数恰巧是调用引用方法的对象(其引用方法所在类或其父类类型)也即是函数接口第一个参数去调用存在于引用方法所在类或其子类的实例方法
或者下面这样理解
②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时
分析:
BiPredicate函数接口中有两个参数boolean test(T var1, U var2);两个参数String 中的实际equals方法: boolean equals(Object anObject) 一个参数
BiPredicate比String中equal参数多一个,并且调用equal的x的类型跟函数接口第一个参数一样都是String类型的
public void test04() {
BiPredicate<String,String> bpp = (x,y) -> x.equals(y);// ②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
BiPredicate<String,String> bp = String::equals;}
public class TestClassMethod01 {
public void a(){
}
public void b(Integer param1,String param2){
}
public void c(Integer param1,int param2){
}
public void d(Integer param1,int param2){
}
public static void main(String[] args) {
MyInter<TestClassMethod01> m = TestClassMethod01::a;
System.out.println("创建a对象成功");
MyInter02<TestClassMethod01> m2 = TestClassMethod01::b;
System.out.println("创建b对象成功");
MyInter03<TestClassMethod01> m3 = TestClassMethod01::c;
System.out.println("创建c对象成功");
//第一个参数为方法目标,其余参数为参数
MyInter04<TestClassMethod01> m4 = (x,y,z) -> x.d(y,z);
System.out.println("创建d对象成功");
}
}
@FunctionalInterface
interface MyInter<T> {
//入参参数比Test1的a方法多一个,且Test1::a的TestClassMethod01与该入参类型TestClassMethod01相同
public void d(T d);
}
@FunctionalInterface
interface MyInter02<T> {
//该接口参数比上述的a方法参数数量多一个,除去第一个,其它类型一致(可兼容,如可以一个int,一个Integer)
//且Test1::a的Test1是该入参类型Test1相同
public void d(T d,int param1,String param2);
}
@FunctionalInterface
interface MyInter03<T> {
//该接口参数比上述的a方法参数数量多一个,除去第一个,其它类型一致(可兼容,如可以一个int,一个Integer)
//且Test1::a的Test1是该入参类型Test2的子类(不可颠倒)
public void d(T d,int param1,int param2);
}
@FunctionalInterface
interface MyInter04<T> {
public void d(T d,int param1,int param2);
}
//分析:
//BiPredicate函数接口中有两个参数,比String中equal参数多一个,并且调用equal的x的类型跟函
//数接口第一个参数一样都是String类型的
public void test04() {
BiPredicate<String,String> bpp = (x,y) -> x.equals(y);
// ②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
BiPredicate<String,String> bp = String::equals;
}
4 构造方法引用
组成语法格式:Class::new
// 1. 类名 :: new
@Test
public void test05() {
Supplier<Employee> em = () -> new Employee();
Supplier<Employee> em2 = Employee::new;
//引用方法的参数列表和返回值类型跟接口方法中参数列表和返回值类型一样,这里就是new了一个无参的对象。
}
@Test
public void test06() {
Function<String,Employee> fun = (x) -> new Employee(x);
Function<String,Employee> fun2 = Employee::new;
BiFunction<String,Integer,Employee> function = Employee::new;
}
5 数组构造方法引用
组成语法格式:TypeName[]::new
// 类型[] :: new;
@Test
public void test07() {
Function<Integer,String[]> fun = (x)-> new String[x];
String[] strings = fun.apply(10);
System.out.println(strings.length);
Function<Integer,String[]> fun2 = String[] :: new;
String[] strings1 = fun2.apply(39);
System.out.println(strings1.length);
}