Lambda表达式

Lambda表达式

函数式编程思想概述

y = x + 1,在数学中,函数就是有输入量,输出量的一套计算方案;也就是拿什么东西,做什么事情。 相对而言,面向对象过分强调必须通过对象的形式来做事情。而函数式编程思想则尽量忽略面向对象的复杂语句—强调的是做什么,而不是以什么方式来做

面向对象的思想:

​ 做一件事情,找一个能解决这些事情的对象,调用对象的方法来完成事情

函数式编程思想:

​ 忽略了面向对象的复杂语法,只要能获得事情的结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程。

lambda表达式的标准格式:

由三部分组成:
1:一些参数1,2,3,…n
2:一个箭头
3:一段代码
格式:

(参数列表) -> {一些重写run方法的代码};

​ 格式说明:

  • () : 接口中抽象方法的参数列表,于传统方法的参数列表一致,参数列表可以没有参数,就空着,又参数就写出参数,多个参数使用逗号隔开
  • -> : 新引入的语法格式,传递的意思,把方法中的参数传递个方法体
  • {} : 重写接口的抽象方法的方法体,于传统方法体要求基本一致
冗余的Runnable代码

​ 当需要启动一个线程去完成一项任务时,通常会通过Runnable接口来定义任务内容,并且使用Thread类来启动线程。

new Thread(new Runnable() {
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "--> 新线程被创建了");
	}
}).start();
代码分析:

​ 对于Runnable的匿名内部类可以分析出以下内容

  • Thread类需要Runnable接口作为参数,其中抽象方法run用来指定线程任务内容的核心
  • 为了指定run方法的方法体,不得不需要Runnable接口的实现类
  • 为了省去定义一个Runnable实现类的麻烦,不得不定义一个匿名内部类
  • 必须重写抽象方法run方法,所以方法的名称,方法的参数,方法的返回值不得不再写一遍,且不能写错
  • 从这里面可以看出,只有方法体才是线程任务的关键性内容
编程思想的转换

我们希望做的事情是:将run方法体内的代码传递给Thread类,让Thread知晓能够加载即可。
传递一段代码–是我们真正的目的,
我们需要将程序关注的重点从怎么做回归到做什么,过程于形式并不重要。

2014年3月Oracle官方所发布的Java8 (JDK1.8)中,加入了Lambda表达式 (λ)

Lambda表达式的更优写法
new Thread(() -> {
	System.out.println(Thread.currentThread().getName() + "--> 新线程被创建了");
}).start();

从上面的可以看出,没有创建接口的实现类对象,也不再有抽象方法覆盖重写的操作,只写了线程任务的内容。

  • 前面的一对()几位run方法,参数无,里面是空的,此时不需要任何的条件
  • 中间的一个箭头代表将前面的参数传递给后面的代码
  • 后面的输出语句即使业务逻辑代码(线程任务内容)

定义一个厨子,厨子是一个接口,在接口内内置了一个做饭的方法(抽象方法),且无参数,无返回值

public interface Cook {
	void zuoFan();
}
public class TestC {
	public static void main(String[] args) {
		//使用Lambda表达式简化
		invokeFood(()->{
			System.out.println("吃饭");
		});	
	}
	public static void invokeFood(Cook cook) {
		cook.zuoFan();
	}
}

使用数组存储多个学生对象,对数组中的学生对象使用Arrays的sort方法通过年龄进行升序排序。使用Lambda表达式来实现以上需求。(有参无返回)

public class Student {
	private String name;
	private Integer age;
    public Student(String name, Integer age) {
		this.name = name;
		this.age = age;
	}
}
public class TestS {
	public static void main(String[] args) {
		Student[] students = {new Student("小孙",20),
				new Student("小刘",18),new Student("小找",25),new Student("小王",21)};
		//传统方法,匿名内部类
		Arrays.sort(students,new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				return s1.getAge() - s2.getAge();
			}
		});
		//使用lambda表达式来简化
		Arrays.sort(students,(Student s1,Student s2)->{
			return s1.getAge() - s2.getAge();
		});
		//遍历输出
		for (Student student : students) {
			System.out.println(student);
		}	
	}
}

给定一个计算器接口,内置了一个抽象方法计算的方法,可以将两个double类型的数字相加得到和值。使用Lambda表达式来实现以上需求。(有参有返回)

public interface Calc {
	//定义一个求和的方法
	double sum(double d1,double d2);
}
public class DemoCalc {
	public static void main(String[] args) {
		// lambda表达式
		invokeSum(3.14, 3.15, (double d1, double d2) -> {
			return d1 + d2;
		});
		// 传统写法
		invokeSum(3.14, 3.15, new Calc() {
			@Override
			public double sum(double d1, double d2) {
				return d1 + d2;
			}
		});
	}
	// 定义一个方法,参数传递连个值,在传递一个接口
	public static void invokeSum(Double d1, Double d2, Calc calc) {
		double sum = calc.sum(d1, d2);
		System.out.println("d1 + d2的和为: " + sum);
	}
}

Lambda省略格式

可推导可省略

Lambda表达式强调的是"做什么",而不是"怎么做",凡是可以根据上下文推导得知的信息,都可以省略,比如:

invokeSum(3.14, 3.15, (double d1, double d2) -> {
	return d1 + d2;
});
省略格式表达
invokeSum(3.14,3.15,(d1,d2) -> d1 + d2)

省略规则:

​ 在Lambda标准格式的表达式的基础上,使用省略写法的规则是:

  • 小括号内参数的类型可以省略
  • 如果小括号内有且仅有一个参数,则小括号也可以省略
  • 如果大括号内有且仅有一个语句,则无论是否又返回值,都可以省略大括号,return关键字和语句的分号。

可以省略的内容:

  1. 参数列表,括号中的参数列表的数据类型,可以省略不写
  2. 参数列表,括号中的参数只有一个,那么类型和小括号都可以省略
  3. {一些代码}:如果{}中的代码只有一行,无论是否有返回值,都可以省略,({},return,分号),但是:要省略{},return,分号 需要一起省略

Lambda的使用前提

​ Lambda的语法非常的简介,使用非常的简单,但是又以下注意事项:

  1. 使用Lambda必须具有接口,且要求接口中有且只有一个抽象的方法

    无论JDK内置的Runnable,Comparator接口还是自定义的接口,只有当接口中的抽象方法存在且唯一,才能使用Lambda

  2. 使用Lambda必须具有上下文推断。

    也就式方法的参数或者局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。

备注:如果有且仅有一个抽方法的接口,称为函数式接口

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值