lambda表达式:

lambda表达式:

使用场景:

1.使用lambda表达式是为了简化接口实现,本质上只是一个匿名函数,可以使用这个匿名函数实现接口中的方法,对接口进行非常简单的实现,从而简化代码

2.lanbda表达式是能实现函数式接口

函数式接口的概念:

如果说,一个接口中要求实现磊必须实现的抽象方法,有且只有一个,这样的接口,就是函数式接口

@FunctionalInterface:是一个注解,用在接口之前,判断这个接口是否是一个函数式接口,如果是一个函数式接口,如果不是函数时接口,没有问题,但如果不是函数式接口,则会报错,功能类似于@Override

语法:

lambda表达式,本质上来讲就是一个匿名函数,因此在写lambda表达式的时候,不需要关心方法名是什么,实际上,我们在写lambda表达式的时候,也不需要关心返回值类型,只需要关注两部分内容:参数列表和方法体

(参数)->{
方法体
};
/*
参数部分:方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型
方法体部分:方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回
->:分隔参数部分和方法体部分
*/

lambda表达式的进阶:

参数部分的精简:

参数的类型:
由于在接口的方法中,已经定义了每一个参数的类型是什么,而在使用lambda表达式实现接口的时候,必须保证参数的数量和类型需要和接口中方法保持一致,因此lambda表达式中的参数可以省略不写
(注意事项):
如果需要省略参数的类型,要保证:每一个参数的类型都省略不写,绝对不能出现,有的参数省略了,有的参数没有省略。
-----------------------------------------------------------------------------------
参数的小括号:
如果方法的参数列表中的参数数量有且仅有一个,此时的小括号是可以省略不写的
(注意事项):
只有当参数的数量是一个的时候,多了,少了都不能省略
省略掉小括号时,必须要省略参数的类型

方法体部分的精简:

方法体中的大括号的精简:
    当方法体中的逻辑,有且仅有一句的情况下,大括号可以省略不写
 return的精简:
    如果一个方法中的唯一的一条语句是一个返回语句,此时在省略大括号的同时,也必须省略掉return

函数引用:

lambda表达式是为了简化接口的实现。在lambda表达式中,不应该出现比较复杂的逻辑,如果在lambda表达式中出现了过于复杂的逻辑,会对程序的可读性造成非常大的影响,如果在lambda表达式中需要处理的逻辑比较复杂,一般情况下会单独的写一个方法,在lambda表达式中直接引用这个方法即可

或者在一些情况下,我们需要使用lambda表达式中实现的逻辑,在另一个地方已经写好了,此时我们就不需要再单独写一遍,只需要引出这个一斤存在的方法即可

函数引用:引用一个已经存在的方法,使其替代lambda表达式完成接口的实现

静态方法的引用:

package bk.javase.p528;
/*
静态方法的引用:
注意事项:
在引用方法的后面,不需要添加小括号
引用这个方法,参数(数量,类型)和返回值,必须和接口中定义的一致
 */
public class demo5 {
    public static void main(String[] args) {
        //实现对一个或多个参数的,一个返回值的接口
        //对一个静态方法的引用
        //语法:类名::静态方法
        SingleReturnMutiple lambda1 = Calculator::calculate;
        System.out.println(lambda1.test(10,20));

    }
        private static class Calculator{
            public static int calculate(int a,int b){
                //我们将稍微复杂的计算逻辑放到方法中
                if (a > b){
                    return a-b;
                }else{
                    return b-a;
                }
            }
        }

}
@FunctionalInterface
interface SingleReturnMutiple{
    int test(int a,int b);
}

非静态方法的引用:

package bk.javase.p528;
/*
非静态方法的引用:
注意事项:
在引用的方法后面,不要添加小括号
引用的这个方法,参数(数量,类型)和返回值,必须和接口中定义的一致
 */
public class demo6 {
    public static void main(String[] args) {
        //对非静态方法的引用,需要使用对象来完成
        //语法:匿名对象::非静态类方法
        SingleReturnMutipleParameters lambda = new Calculator()::calculate;
        System.out.println(lambda.test(10,20));

    }
        private static class Calculator{
            public int calculate(int a,int b){
                return a > b ?a-b:b-a;
            }
        }



}
@FunctionalInterface
interface SingleReturnMutipleParameters{
    int test(int a,int b);
}

构造方法的引用:

package bk.javase.p528;
/*
构造方法的引用:
如果在一个函数式接口定义的方法,仅仅是为了得到一个类的对象,
此时我们就可以使用构造方法的引用,简化这个方法的实现
注意事项:
可以通过接口中的方法的参数,区分不同的构造方法
 */
public class demo7 {
    public static void main(String[] args){

        //lambda表达式实现接口
        GetPerson lambda = Person::new;
        //引用到Person类中的无参构造方法,获取到一个Person对象
        Person person = lambda.test();

        //引用到Person类中的有参构造方法,获取到一个Person对象
        GetPersonParameter lambda2 = Person::new;
        lambda2.test("xiaoming",1);
    }

    private static class Person{
        String name;
        int age;
        public Person(){
            System.out.println("一个Person对象被实例化了");
        }
        public Person(String name,int age){
            System.out.println("一个Person对象被有参构造实例化了");
            this.name = name;
            this.age = age;
        }
    }

    @FunctionalInterface
    private interface GetPerson{
        //仅仅是希望获取到一个Person对象作为返回值
        Person test();
    }

    private interface GetPersonParameter{
        Person test(String name,int age);
    }
}

对象方法的特殊引用:

package bk.javase.p528;
/*
对象方法的特殊引用
如果在使用lambda表达式,实现某些接口时,lambda表达式中包含了某一个对象,此时方法体中
直接使用这个对象调用它的某一个方法就可以完成整体的逻辑,其他的参数,可以作为调用方法的参数
此时,可以对这种实现进行简化
 */
public class demo8 {
    public static void main(String[] args){

        //如果对于这个方法的实现逻辑,是为了获得到对象的名字
        GetField field = person -> person.getName();


        //对于对象方法的特殊引用
        GetField fields = Person::getName;


        //如果对于这个方法的实现逻辑,是为了给对象的某些属性进行赋值
        SetField lambda = (person,name)->person.setName(name);
        SetField lambda2 = Person::setName;

    }

}
interface ShowTest{
    void test(Person person);
}

interface SetField{
    void set(Person person,String name);
}
interface GetField{
    String get(Person person);
}

class Person{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){

    }
}

使用lambda表达式要注意的问题:

类似于局部内部类,匿名内部类,依然存在闭包的问题

如果在lambda表达式中,使用到了局部变量,那么这个局部变量会被隐式的声明为final,放到常量池中,是一个常量,不能修改值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值