Lambda表达式(优雅永不过时 )

目录

1.什么是Lambda表达式

2.使用前提

3.基本使用

3.1.语法:()->{}

3.2.具体使用(这里举了几个简单的接口例子)

3.3.方法引用

3.3.1.方法引用的条件

3.3.2.方法引用的语法


1.什么是Lambda表达式

  • Lambda表达式是JDK8的一个新特性,可以取代接口的匿名内部类,能让你写出更加优雅的代码 。
  • 它可以写出更加简洁,更加灵活的代码,作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升 。
  • 他是一种高端的玩法,人上人的玩法

2.使用前提

  • 并不是所有的接口都能使用Lambda表达式创建子类对象,只有功能接口才能使用。
  • Lambda表达式要求的接口中,必须有且仅有一个必须要实现的抽象方法。这种接口在Java中,被称之为"功能接口" 。
  • 功能接口语法上使用注解@FunctionalInterface标记在接口头上用来检测一个接口是不是功能接口 。

就比如这样,加上@FunctionalInterface不报错他就是功能接口

@FunctionalInterface
interface I{
    void test();
}

那么思考两个问题 :

    1.功能接口中只能有一个方法吗?

        答案肯定是不是,Java8中的默认方法和静态方法不需要子类实现,功能接口中可以允许有它们存在。

// 就比如这样它依然是功能接口,并不会报错

@FunctionalInterface
interface IA{
    void test();
    default void test2(){};
    static void test3(){};
}

   

2.功能接口中只能有一个抽象方法吗?

         不是,有极个别比较特殊的抽象方法,可以不需要子类实现:就比如

         Object类是Java每一个类的父类,所以Object类当中的方法实现就可以作为接口抽象方法的实现。

// 重写了equals和hashcode方法它依然是功能接口 因为他们不是必须要实现的抽象方法

@FunctionalInterface
interface IB{
    void test();
    boolean equals(Object obj);
    int hashCode();
}

再强调一下,功能接口指的是有且仅有一个必须要子类实现的抽象方法的接口

3.基本使用

3.1.语法:()->{}

(形参列表) -> {
// 方法体
}

解释一下:

  • (形参列表)表示功能接口中,必须要重写的抽象方法的形参列表。
  • ->由一个英文横杠 + 英文大于号字符组成,它是Lambda表达式的运算符,读作goes to
  • { //方法体 }表示功能接口中,必须要重写的抽象方法的,方法体实现。

3.2.具体使用(这里举了几个简单的接口例子)

  • 无参无返回值的
// 接口
@FunctionalInterface
interface IC{
    void test();
}
// Lambda实现
IC ic = ()->{ System.out.println("起飞666"); };
         ic.test();

  • 需要一个参数但无返回值
// 接口
@FunctionalInterface
interface ID{
    void test(int a);
// Lambda实现
ID id = (int a) -> {System.out.println("我输出了" + a);};
        id.test(18);

  • 数据类型可以省略,编译器会自动进行类型推断
// 接口
@FunctionalInterface
interface ID{
    void test(int a);
// Lambda实现
ID id = (a) -> {System.out.println("我输出了" + a);};
        id.test(18);

  • lambda若只需要一个参数时,参数的小括号可以省略
// 接口
@FunctionalInterface
interface ID{
    void test(int a);,
// Lambda实现
 ID id = a -> {System.out.println("我输出了" + a);};
        id.test(18);

  • 当重写方法的方法体的语句仅有一条语句时,那么可以省略大括号,特殊的,当这一条语句就是方法的返回值语句时,那么{}和return可以一起省略。
// 接口
interface IE{
    int test(int a,int b);
// Lambda实现
IE ie = (a, b) -> a+b;
    System.out.println(ie.test(129,391));

3.3.方法引用

       实际上在多数情况下,都不太可能一句话把方法体写完。多数情况下,Lambda表达式的抽象方法实现都会很复杂,那这样Lambda表达式就会写的很复杂,这就很难受了。而Lambda表达式,本质上就是重写了一个抽象方法的子类对象,所以Java允许Lambda表达式的抽象方法的实现可以直接指向一个已经存在的方法,而不是自己书写实现。这种语法在Java中称之为"方法引用"!

3.3.1.方法引用的条件

  • 访问权限修饰符和static之类的修饰符,实际上没有多大影响,但是肯定需要访问权限。
  • 返回值类型应该保持一致(如果抽象方法返回一个父类引用类型、那么这个已实现的方法可以返回子类类型)。
  • 方法名是什么不重要。
  • 形参列表必须保持一致、数据类型、位置必须严格对应,但是形参名无所谓。
  • 方法体无所谓,自己重写即可。

3.3.2.方法引用的语法

  • 不去掉运算符的格式:(形参列表) -> 已实现的方法(形参列表);
  1. 如果这个方法是静态方法,用类名.调用
  2. 如果是个成员方法,用对象名.调用
  3. 上述语法中的形参列表必须保持一致,表示将抽象方法中形参传递给已实现的方法
// 重写的接口
/*
*功能接口
* 无参无返回值
* */
@FunctionalInterface
interface IC{
    void test();
}

/*
* 需要一个参数但无返回值
* */
@FunctionalInterface
interface ID{
    void test(int a);

}

/*
*int 返回值 两个参数
*/
@FunctionalInterface
interface IE{
    int test(int a,int b);
// 方法的引用
public void test1(){
        System.out.println(666);
        System.out.println(666);
        System.out.println(666);
    }

    public void test2(int a){
        System.out.println(777);
        System.out.println(777);
        System.out.println(777);
        System.out.println(a);
    }

    public static int test3(int a,int b){
        System.out.println(888);
        System.out.println(888);
        System.out.println(888);
        return a+b;
    }
// Lambda 调用
        IC ic1 = ()-> new MyTest().test1();
        ic1.test();
       
        ID id1 = a -> new MyTest().test2(a);
        id1.test(9420);
        
        IE ie1 = (a,b) -> MyTest.test3(a,b);
        System.out.println(ie1.test(100, 200));

  • 功能接口 引用名 = 方法的归属者::方法名
// 还是上面的三个接口 用第二种方法实现
      IC ic2 = new MyTest()::test1;
      ic2.test();

      ID id2 = new MyTest()::test2;
      id2.test(99);

      IE ie2 = MyTest::test3;
      System.out.println(ie2.test(99,999));

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值