java8特性之Lambda表达式
1.典型的用Lambda表达式的场景
如果有这样的一个小应用,其中的一个类Student包含姓名(name),性别(sex),分数(score),如下:
package demo;
public class Student {
public enum Sex {
MALE,FEMALE
}
private String name;
private Sex gender;
private int age;
private double score;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, Sex gender, int age, double score) {
super();
this.name = name;
this.gender = gender;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Sex getGender() {
return gender;
}
public void setGender(Sex gender) {
this.gender = gender;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public void printStudent() {
System.out.println("学生姓名:"+this.name);
System.out.println("学生年龄:"+this.age);
System.out.println("学生性别:"+this.gender);
System.out.println("学生成绩:"+this.score);
}
}
假设创建的学生类都放在一个Student的ArrayList<Student>,现如今我们要实现这样的一个功能,输入age,筛选出年龄大于age的学生。这非常简单:
(1) 创建一个方法寻找符合条件的Student对象:
public void printStudnetOlderThan(int age) {
for(Student stu:studentList) {
if (stu.getAge()>age) {
stu.printStudent();
}
}
}
这种方法会使你的application变得非常脆弱,如果你的需求要进行修改,比如筛选出成年人,成绩优秀的,等等,那么你将会重写很多的代码,而且代码将会显得很混乱,给代码的阅读带来不便。
(2) 将筛选条件写在一个独立的类中。
package demo;
public interface CheckStudent {
public boolean test(Student stu);
}
package demo;
public class CheckStudentForOlder implements CheckStudent {
@Override
public boolean test(Student stu) {
if (stu.getAge()>18) return true;
return false;
}
}
public void printStudnetOlderThan(CheckStudent tester) {
for (Student stu:studentList) {
if(tester.test(stu)) {
stu.printStudent();
}
}
}
这样就不会出现printStudentOlderThan函数因为筛选条件的改变,而重写多次。但是缺点也是显而易见的你必须为你的每一个筛选条件都创建一个继承CheckStudnet的类,虽然这样代码是比第一中方法更加有条理,但还是显得很臃肿。
(3)创建匿名类
mock.printStudnetOlderThan(new CheckStudent() {
@Override
public boolean test(Student stu) {
if (stu.getAge()>18) return true;
return false;
}
});
这运用了java匿名对象的特性,相比于上一种创建大量筛选类的方法来说,已经帮我们节省了大量创建类的繁琐代码。但是给人的感觉不是很好,代码的功能并不是很明显。
(4)利用Lambda表达式
这个CheckStudent接口是一个function interface(只有一个抽象方法),因此你可以在继承它时,省略掉这个方法的名字,你可以使用Lambda表达式
mock.printStudnetOlderThan((Student p)->p.getAge()>20);
(5) 使用一个标准的Function Interfaces 用于Lambda表达式
JDK定义了几个标准Function Interfaces(只包含一个抽象方法),你可以在 java.util.function.中找到他。
这样就可以避免创建一个接口了。
public void printStudnetOlderThan(Predicate<Student> tester) {
for (Student stu:studentList) {
if(tester.test(stu)) {
stu.printStudent();
}
}
}
//调用上面的函数
mock.printStudnetOlderThan((Student p)->p.getAge()>20);
(6) 使用Consumer<T>来优化代码
我们可以根据上面的代码使得筛选条件可以用Lambda表达式快速的更换,使得程序更加健壮,但是如果在满足筛选条件时,我们想执行的不是printStudent方法,而是其他方法呢?这时,Consumer就可以帮助我们解决这个问题了。
public void printStudnetOlderThan(Predicate<Student> tester,Consumer<Student> block) {
for (Student stu:studentList) {
if(tester.test(stu)) {
block.accept(stu);
}
}
}
//调用
mock.printStudnetOlderThan((Student p)->p.getAge()>20,
p->p.printStudent());
2.Lambda表达式的语法:
(1) 一个带有()用”,”分割的参数列表,你可以省略参数的数据类型。另外如果只有一 个参数你也可以省略掉括号
(2) 箭头符号:->
(3) 用单个表达式或语句块组成的主体。这里需注意如果是语句块要用{}括起来。
3.Target Typing
你怎么样确定一个Lambda 表达式的类型。在上面的例子中我们在方法中调用Lambda表达式,分别用了 Function Interface ,Predicate,Consumer,我们还可以用Function,
只有在java的编译器可以通过上下文找到Lambda表达式的Target Type,你才可以使用Lambda表达式。
java8特性之Lambda表达式的更多相关文章
- java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合
java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...
- Java8 新特性学习 Lambda表达式 和 Stream 用法案例
Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...
- 夯实Java基础(二十二)——Java8新特性之Lambda表达式
1.前言 Java 8于14年发布到现在已经有5年时间了,经过时间的磨练,毫无疑问,Java 8是继Java 5(发布于2004年)之后的又一个非常最重要的版本.因为Java 8里面出现了非常多新的特 ...
- java8的新特性之lambda表达式和方法引用
1.1. Lambda表达式 通过具体的实例去体会lambda表达式对于我们代码的简化,其实我们不去深究他的底层原理和背景,仅仅从用法上去理解,关注两方面: lambda表达式是Java8的一个语法糖 ...
- Java8学习笔记----Lambda表达式 (转)
Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...
- JAVA8学习——深入浅出Lambda表达式(学习过程)
JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...
- Java8特性之Lambda、方法引用以及Stream流
Java 8 中的 Streams API 详解:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ Java笔记——Jav ...
- java8:(Lambda 表达式简介)
JDK8的新特性——Lambda表达式 JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分 ...
- Java8新特性之Lambda表达式
lambda表达式是java8给我们带来的几个重量级新特性之一,借用lambda表达式,可以让我们的java程序设计更加简洁.最近新的项目摒弃了1.6的版本,全面基于java8进行开发,本文是java ...
随机推荐
- loadrunner12-添加集合点
1.首先添加集合点之前要插入事务,集合点和事务通常是一起使用的,单独使用集合点,基本上可以说是没有意义的. 2.在开始事务之前 ,插入一个“集合点”,那么在多用户执行时,就可以将用户请求停下来,直到用 ...
- LWIP带UCOS操作系统移植
LWIP支持RAW.NETCONN.SOCKET这三种编程接口,后两者必须有操作系统来支持的:LWIP带操作系统的移植很重要!!
- html5标签---不常用新标签的整理
状态标签 meter 用来显示已知范围的标量值或者分数值. value:当前的数值. min:值域的最小边界值.如果设置了,它必须比最大值要小.如果没设置,默认为0 max:值域的上限边界值.如果设置 ...
- not in查询不出数据问题
select ID from SmartCustomer where ID not in (select distinct CustomerID from SmartPromoter where Cu ...
- Html::a 生成 method=post
<?= Html::a(Yii::t('app', 'delete'), ['delete', 'id' => $model->id], [ 'class' => 'btn b ...
- ettercap 命令
本地主机:192.168.0.149 目标主机:192.168.0.138 /etc/ettercap/etter.dns,将dns欺骗到本机 ettercap -T -q -i wlan0 -P d ...
- ADF文件数据结构解析和ADF文件读写
包括位姿和特征点位置和描述信息. What does an Area Description File (ADF) looks like? 4down votefavorite 2 I'm start ...
- unity 确定敌人行走路线
一开始搞这个问题很头疼,无从下手. 1.敌人在随机地点产生后,每个敌人有要有自己自动的行走路线,目的地是保护地,而且行走路线要多样化. 2.敌人在看到玩家时,改变行走路线,向玩家的方向行进,且到了一定 ...
- Digester学习笔记(三)转载
总觉得,Digester不仅仅能作配置文件解析,而且可以作得更多. 配置属性 Digester用来解析应用系统的配置文件,其本身也有很可配置的属性. 属性 描述 classLoader 指定类装载器( ...
- 洛谷P2147[SDOI2008]洞穴勘测(lct)
题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...