凯哥带你从零学大数据系列之Java篇---第二十二章 Lambda表达式_千锋教育lambda表达式资料

    System.out.println(parameter1.test(10));
    System.out.println(parameter2.test(10));
    System.out.println(parameter3.test(10));
}

private static class Impl implements SingleReturnSingleParameter {

    @Override
    public int test(int a) {
        return a * a;
    }
}

}


### **22.1.3. Lambda表达式对接口的要求**


虽然说, lambda表达式可以在一定程度上简化接口的实现。 但是, 并不是所有的接口都可以使用lambda表达式来简洁实现的。


lambda表达式毕竟只是一个匿名方法。 当实现的接口中的方法过多或者多少的时候, lambda表达式都是不适用的。


lambda表达式,只能实现**函数式接口**。


**22.1.4. 函数式接口**


**22.1.4.1. 基础概念**


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



// 这个接口中, 有且只有一个方法, 是实现类必须实现的, 因此是一个函数式接口
interface Test1 {
void test();
}
// 这个接口中, 实现类必须要实现的方法, 有两个! 因此不是一个函数式接口
interface Test2 {
void test1();
void test2();
}
// 这个接口中, 实现类必须要实现的方法, 有零个! 因此不是一个函数式接口
interface Test3 {

}
// 这个接口中, 虽然没有定义任何的方法, 但是可以从父接口中继承到一个抽象方法的。 是一个函数式接口
interface Test4 extends Test1 {

}
// 这个接口, 虽然里面定义了两个方法, 但是defualt方法子类不是必须实现的。
// 因此, 实现类实现这个接口的时候, 必须实现的方法只有一个! 是一个函数式接口。
interface Test5 {
void test5();
default void test() {}
}
// 这个接口中的 toString 方法, 是Object类中定义的方法。
// 此时, 实现类在实现接口的时候, toString可以不重写的! 因为可以从父类Object中继承到!
// 此时, 实现类在实现接口的时候, 有且只有一个方法是必须要重写的。 是一个函数式接口!
interface Test6 {
void test6();
String toString();
}




思考题: 下面的两个接口是不是函数式接口?

interface Test7 {
String toString();
}

interface Test8 {
void test();
default void test1() {}
static void test2() {}
String toString();
}


#### **22.1.4.2. @FunctionalInterface**


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



@FunctionalInterface
interface FunctionalInterfaceTest {
void test();
}


**22.1.4.3. 系统内置的若干函数式接口**


![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMzLnpoaW1nLmNvbS84MC92Mi1kMzU2YWE4OWMzZTg4Mjk2YWMzODViZDQyNDNjNzk0YV83MjB3LmpwZw?x-oss-process=image/format,png)


**22.2. Lambda表达式的语法**


### **22.2.1. Lambda表达式的基础语法**


lambda表达式, 其实本质来讲, 就是一个匿名函数。 因此在写lambda表达式的时候, 不需要关心方法名是什么。


实际上, 我们在写lambda表达式的时候, 也不需要关心返回值类型。


我们在写lambda表达式的时候, 只需要关注两部分内容即可: **参数列表** 和 **方法体**


**lambda表达式的基础语法:**



(参数) ->{
方法体
};


**参数部分** : 方法的参数列表, 要求和实现的接口中的方法参数部分一致, 包括参数的数量和类型。


**方法体部分 :** 方法的实现部分, 如果接口中定义的方法有返回值, 则在实现的时候, 注意返回值的返回。


**->** : 分隔参数部分和方法体部分。



/**

  • @Description
    */
    public class Syntax {
    public static void main(String[] args) {
    // 1. 无参、无返回值的方法实现
    NoneReturnNoneParameter lambda1 = () -> {
    System.out.println(“无参、无返回值方法的实现”);
    };
    lambda1.test();

     // 2. 有参、无返回值的方法实现
     NoneReturnSingleParameter lambda2 = (int a) -> {
         System.out.println("一个参数、无返回值方法的实现: 参数是 " + a);
     };
     lambda2.test(10);
    
     // 3. 多个参数、无返回值方法的实现
     NoneReturnMutipleParameter lambda3 = (int a, int b) -> {
         System.out.println("多个参数、无返回值方法的实现: 参数a是 " + a + ", 参数b是 " + b);
     };
     lambda3.test(10, 20);
    
     // 4. 无参、有返回值的方法的实现
     SingleReturnNoneParameter lambda4 = () -> {
         System.out.println("无参、有返回值方法的实现");
         return 666;
     };
     System.out.println(lambda4.test());
    
     // 5. 一个参数、有返回值的方法实现
     SingleReturnSingleParameter lambda5 = (int a) -> {
         System.out.println("一个参数、有返回值的方法实现: 参数是 " + a);
         return a * a;
     };
     System.out.println(lambda5.test(9));
    
     // 6. 多个参数、有返回值的方法实现
     SingleReturnMutipleParameter lambda6 = (int a, int b) -> {
         System.out.println("多个参数、有返回值的方法实现: 参数a是 " + a + ", 参数b是 " + b);
         return a * b;
     };
     System.out.println(lambda6.test(10, 20));
    

    }
    }


### **22.2.2. Lambda表达式的语法进阶**


在上述代码中, 的确可以使用lambda表达式实现接口, 但是依然不够简洁, 有简化的空间。


#### **22.2.2.1. 参数部分的精简**


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



// 多个参数、无返回值的方法实现
NoneReturnMutipleParameter lambda1 = (a, b) -> {
System.out.println("多个参数、无返回值方法的实现: 参数a是 " + a + ", 参数b是 " + b);
};


* 参数的小括号
	+ 如果方法的参数列表中的参数数量 **有且只有一个** ,此时,参数列表的小括号是可以省略不写的。
	+ 注意事项:
		- 只有当参数的数量是一个的时候, 多了、少了都不能省略。
		- 省略掉小括号的同时, 必须要省略参数的类型。



// 有参、无返回值的方法实现
NoneReturnSingleParameter lambda2 = a -> {
System.out.println("一个参数、无返回值方法的实现: 参数是 " + a);
};


**22.2.2.2. 方法体部分的精简**


* 方法体大括号的精简
	+ 当一个方法体中的逻辑, 有且只有一句的情况下, 大括号可以省略。



// 有参、无返回值的方法实现
NoneReturnSingleParameter lambda2 = a -> System.out.println("一个参数、无返回值方法的实现: 参数是 " + a);


* return的精简
	+ 如果一个方法中唯一的一条语句是一个返回语句, 此时在省略掉大括号的同时, 也必须省略掉return。



SingleReturnMutipleParameter lambda3 = (a, b) -> a + b;


**22.3. 函数引用**


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



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


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


**22.3.1. 静态方法的引用**


* **语法:**
	+ 类::静态方法



* **注意事项:**
	+ 在引用的方法后面, 不要添加小括号。
	+ 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的一致。



* **示例:**



/**

  • @Description
    */
    public class Syntax1 {
    // 静态方法的引用
    public static void main(String[] args) {
    // 实现一个多个参数的、一个返回值的接口
    // 对一个静态方法的引用
    // 类::静态方法
    SingleReturnMutipleParameter lambda1 = Calculator::calculate;
    System.out.println(lambda1.test(10, 20));
    }

    private static class Calculator {
    public static int calculate(int a, int b) {
    // 稍微复杂的逻辑:计算a和b的差值的绝对值
    if (a > b) {
    return a - b;
    }
    return b - a;
    }
    }
    }


**22.3.2. 非静态方法的引用**


* **语法:**
	+ 对象::非静态方法



* **注意事项:**
	+ 在引用的方法后面, 不要添加小括号。
	+ 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的一致。



* **示例:**



/**

  • @Description
    */
    public class Syntax2 {
    public static void main(String[] args) {
    // 对非静态方法的引用,需要使用对象来完成
    SingleReturnMutipleParameter lambda = new Calculator()::calculate;
    System.out.println(lambda.test(10, 30));
    }

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


### **22.3.3. 构造方法的引用**




![img](https://img-blog.csdnimg.cn/img_convert/b9da37f24d0c7bf47eab11474ccb1c91.png)
![img](https://img-blog.csdnimg.cn/img_convert/ab6641bd585a9694d6068299a766ed76.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

``

### **22.3.3. 构造方法的引用**




[外链图片转存中...(img-TMtQ9ucQ-1714752476161)]
[外链图片转存中...(img-yHczpBxE-1714752476162)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值