java8:方法引用

  • 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;

    }

 实例对象的方法引用

    这种语法与用于静态方法的语法类似,只不过这里使用对象引用而不是类名。实例方法引用又分以下三种类型:

   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);
    }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值