Java知识点整理 18 — Lambda表达式

一. 简介

Lambda 表达式是函数式编程思想的体现,强调做什么,而不是以什么方式去做。

面向对象编程思想强调的是对象,必须通过对象的形式来做一些事情。比如多线程执行任务,需要创建对象,对象需要实现指定接口,然后再执行等。过程相对繁琐。而如果使用函数式编程思想,可以直接通过传递一段代码给线程对象执行,不需要创建任务对象。

Lambda 表达式可以被视为匿名函数,允许在需要函数的地方以更简洁的方式定义功能

因此只要是函数式接口,就可以使用 Lambda 表达式简化。

函数式接口指的是接口中有且只有一个未实现的方法。如果超过一个,则不是函数式接口;如果有一个默认实现方法,一个未实现的方法,也是函数式接口。

// 接口中有超过一个未实现方法,不是函数式接口
interface MyInterface {
    int sum(int a, int b);
    int min(int a, int b);
}

// 接口中只有一个未实现的方法,是函数式接口
interface MyCase{
    int hello();
    default int hello(int a){return a;} //默认实现
}

可以用 JDK 中提供的检查注解 @FunctionalInterface 来检查该接口是否为函数式接口。

正常情况下:

异常情况下:

 二. Lambda 表达式的格式

1. 标准格式

( 参数列表 )-> { 代码 }

2. 格式说明

小括号内是参数列表,语法与传统方法参数列表一致,没有参数就留空,有多个就用逗号分隔。

箭头符号 ->,代表指向动作。

大括号内是业务逻辑代码,语法与传统方法体一致。

3. 举例

创建线程

// 传统方式
Thread thread1 = new Thread(new Runnable() {
    @Override
    public void run () {
       System.out.println("线程需要执行的任务代码1");
    }
});
thread1.start();
 
// Lambda表达式
Thread t2 = new Thread(()->{
    System.out.println("线程需要执行的任务代码2");
});
t2.start();

比较器

List<Integer> list = new ArrayList<>();
Collections.addAll(list,11,22,33,44,55);
System.out.println("排序之前的集合:" + list);
        
// 传统方式
Collections.sort(list, new Comparator<Integer>() {
    @Override
    public int compare (Integer o1, Integer o2) {
        return o2-o1;
    }
});
 
// Lambda表达式
Collections.sort(list,(Integer o1, Integer o2)->{return o2-o1;});
System.out.println("排序之后的集合:" + list);

三. Lambda 表达式与函数式接口

假如有一个接口 MyInterface,里面有一个方法 sum(),

interface MyInterface {
    int sum(int a, int b);
}

想要实现这个接口,有两种方法:

1. 自己写实现类

class MyInterfaceImpl implements MyInterface {
    @Override
    public int sum(int a, int b) {
        return a + b;
    }
}

然后调用,

public class Lambda {
    public static void main(String[] args) {
        MyInterface myInterface = new MyInterfaceImpl();
        int result = myInterface.sum(1, 2);
        System.out.println(result);
    }
}

2. 创建匿名实现类

每个接口都去写对应的实现类相对麻烦,因此可以采用匿名实现类动态的去实现接口

public class Lambda {
    public static void main(String[] args) {

        // 1. 自己创建实现类对象
        MyInterface myInterface = new MyInterfaceImpl();
        int result = myInterface.sum(1, 2);
        System.out.println("自己创建的实现类对象 " + result);

        // 2. 创建匿名实现类
        MyInterface myInterface1 = new MyInterface() {
            @Override
            public int sum(int a, int b) {
                return a*a + b*b;
            }
        };
        int result1 = myInterface1.sum(1, 2);
        System.out.println("匿名实现类 " + result1);
    }
}

在匿名实现类中,很多格式上的东西都是固定的,因此可以进一步简化,只保留动态的东西,比如参数、方法体内容等,

// 2. 匿名实现类
MyInterface myInterface1 = new MyInterface() {
    @Override
    public int sum(int a, int b) {
       return a*a + b*b;
    }
};

// 3. Lambda表达式实现接口  参数列表 + 箭头 + 方法体
MyInterface myInterface2 = (int a, int b) -> {
    return a * a + b * b;
};

进一步思考,其实参数类型也是固定的,还可以再简化,

MyInterface myInterface3 = (x, y) -> {
     return x * x + y * y;
};

参数名不一定是接口中定义的(a,b),也可以是其它名字,比如(x,y)。

此外,参数部分如果为空,可以留空,即只写一个(),但不能不写括号;或者如果只有一个参数,可以只写一个参数名,

// 入参为控
interface MyCase1{
    int hello();
}

public class Lambda {
    public static void main(String[] args) {
        MyCase myCase1 = () -> {
            return 1;
        };
    }
}

// 只有一个参数 a
interface MyCase2{
    int hello(int a);
}

public class Lambda {
    public static void main(String[] args) {
        MyCase1 myCase2 = a -> {
            return a + 1;
        };
    }
}

方法体如果只有一句话,{ } 和 return 可以省略,

interface MyCase2{
    int hello(int a);
}

public class Lambda {
    public static void main(String[] args) {
        MyCase1 myCase2  = a ->  a + 2;
        // 调用方法
        System.out.println(myCase2.hello(1));
    }
}

四. Lambda 表达式的表现形式 

1. 变量形式

变量的类型为函数式接口(不常用)

// 变量的形式
Runnable r = ()->{
    System.out.println("任务代码");
};
// 函数式接口类型的变量
Thread t = new Thread(r);

2. 参数形式

方法的形参类型为函数式接口(常用)

// 变量的形式-比较器
Comparator<Integer> comparable = (o1, o2)->{return o2 - o1;};

// 创建集合
ArrayList<Integer> list = new ArrayList<>();

// 存入数据
Collections.addAll(list,11,22,33,44,55);
 
// 将函数式接口类型的形参类型,传给Collections
Collections.sort(list,comparable);

3. 返回值形式

方法的返回值类型为函数式接口(常用)

// 定义一个方法
public static Comparator<Integer> getComparator(){
     return (Integer o1,Integer o2)->{return  o2-o1;};
}
        
public static void main (String[] args) {
   // 返回值形式
   Collections.sort(list,getComparator());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Phoenixxxxxxxxxxxxx

感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值