【Java教程】Day19-01 函数式编程:Lambda表达式与功能接口

在了解Lambda之前,我们先回顾一下Java的方法,帮助我们更好地理解函数式编程在Java中的应用。

1. Java的方法概述

在Java中,方法可以分为两大类:实例方法静态方法

1.1 实例方法

实例方法是绑定到类的某个实例上的方法,需要通过实例对象来调用。例如,Integer类的equals()方法:

javapublic final class Integer {    boolean equals(Object o) {        // 实现逻辑    }}

 

此方法的调用需要通过对象来调用,并隐式传入当前对象的引用(即this)。

1.2 静态方法

静态方法属于类本身,不需要通过对象来调用。例如,Integer类的parseInt()方法:

javapublic final class Integer {    public static int parseInt(String s) {        // 实现逻辑    }}

 

静态方法直接通过类名调用,不涉及this参数。

无论是实例方法还是静态方法,本质上都可以看作过程式语言中的函数,只是Java的实例方法隐式地传入了this,即方法的第一个参数是当前对象本身。

2. 什么是函数式编程?

函数式编程(Functional Programming,简称FP)是将函数作为基本运算单元的一种编程范式。在函数式编程中,函数不仅可以作为变量,还可以作为参数传递,也可以作为返回值返回。这种思想来源于Lambda演算(Lambda Calculus),因此很多支持此编程风格的语言(如Java 8及之后的版本)都提供了Lambda表达式。

3. Lambda表达式

3.1 Lambda表达式的简化

在Java中,Lambda表达式允许我们以一种更加简洁的方式传递行为。它可以简化传统匿名内部类的写法。

举个例子,Comparator接口是一个典型的单方法接口。在排序操作中,我们通常会用到这个接口。以下是使用匿名类实现排序的代码:

javaString[] array = {"Apple", "Orange", "Banana", "Lemon"};Arrays.sort(array, new Comparator<String>() {    public int compare(String s1, String s2) {        return s1.compareTo(s2);    }});System.out.println(String.join(", ", array));

 

这段代码看起来很繁琐,特别是Comparator接口的实现部分。使用Lambda表达式,我们可以将代码简化为:


 
javaimport java.util.Arrays;public class Main {    public static void main(String[] args) {        String[] array = {"Apple", "Orange", "Banana", "Lemon"};        Arrays.sort(array, (s1, s2) -> s1.compareTo(s2));        System.out.println(String.join(", ", array));    }}

 

在这段Lambda表达式中:

  • (s1, s2) 是输入参数,类型可以省略,编译器会自动推断类型。

  • -> 表示Lambda表达式的主体,后面的部分是方法体。

  • 在此例中,Lambda表达式中只有一行return语句,因此可以进一步简化。

3.2 Lambda表达式的语法

Lambda表达式的基本语法如下:

java(parameters) -> expression

 

当Lambda表达式有多个参数时,我们需要用括号将其包裹。如果只有一个参数,可以省略括号。如果方法体包含多行代码,代码块需要用花括号包裹,且必须使用return语句返回值。

4. 功能接口(FunctionalInterface)

4.1 什么是功能接口?

在Java中,**功能接口(FunctionalInterface)**是指只包含一个抽象方法的接口。这样的接口非常适合用来作为Lambda表达式的目标类型。

我们可以使用@FunctionalInterface注解来显式声明接口为功能接口。以下是一个典型的功能接口示例:

java@FunctionalInterfacepublic interface Callable<V> {    V call() throws Exception;}

 

4.2 Comparator接口示例

Comparator接口虽然包含多个方法,但它仍然是一个功能接口。因为它只定义了一个抽象方法:compare(),其他方法要么是default方法,要么是static方法。例如:

java@FunctionalInterfacepublic interface Comparator<T> {    int compare(T o1, T o2);    boolean equals(Object obj);  // Object类的方法    default Comparator<T> reversed() {        return Collections.reverseOrder(this);    }    default Comparator<T> thenComparing(Comparator<? super T> other) { ... }}

 

在上面的代码中,Comparator只有一个抽象方法compare(),因此它符合功能接口的定义。

5. Lambda表达式练习

5.1 练习题:使用Lambda表达式实现忽略大小写排序

编写一个程序,使用Lambda表达式对字符串数组进行排序,要求排序时忽略大小写。

javaString[] array = {"Apple", "orange", "banana", "Lemon"};Arrays.sort(array, (s1, s2) -> s1.compareToIgnoreCase(s2));System.out.println(String.join(", ", array));

 

6. 小结

  1. 功能接口:只定义了一个抽象方法的接口被称为功能接口,可以通过@FunctionalInterface注解进行标记。

  2. Lambda表达式:可以用Lambda表达式简化匿名类的写法,使代码更加简洁和易读。

  3. 编译器自动推断:Lambda表达式的参数类型和返回值类型可以由编译器自动推断,极大地减少了代码冗余。

  4. Lambda表达式的应用:Lambda表达式常用于处理单方法接口,特别是在集合框架(如Comparator)的排序操作中。

 

通过以上内容,我们掌握了Lambda表达式的基本使用,并通过具体实例理解了它如何简化代码,提高代码可读性。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值