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 ...
随机推荐
- $_SERVER['HTTP_REFERER']
$_SERVER['HTTP_REFERER']//获取前一个页面的url地址
- [Jenkins] 执行SoapUI的task,设置邮件内容为HTML+CSS
设置邮件内容:Default Content <span style="font-family:verdana;font-size:16px;color:black;font-weig ...
- Ha-Federation-hdfs +Yarn集群部署方式
经过一下午的尝试,终于把这个集群的搭建好了,搭完感觉也没有太大的必要,就当是学习了吧,为之后搭建真实环境做基础. 以下搭建的是一个Ha-Federation-hdfs+Yarn的集群部署. 首先讲一下 ...
- Bootstrap表格类名及对应图形
.table:基础表格 不管制作哪种表格都离不开类名“table”.所以大家在使用Bootstrap表格时,千万注意,你的<table>元素中一定不能缺少类名“table”. .table ...
- C# 集合的使用List<T>的使用
C# List<T>用法 所属命名空间:using System.Collections.Generic; List<T>类是 ArrayList 类的泛型等效类. 该类使用 ...
- python-字符串-技巧
1.删除字符串末尾空白:rstrip函数 test1 = "This is a test " print(test1.rstrip()) 但是这种删除只是暂时的,如果想永久删除,则 ...
- OpenNIDataGet 获取点云数据
运行后,采集的数据保存到:E:\OpenCVData目录下的color和depth文件夹下.接下来要求参数:内参 外参 这些参数最好优化后使用精度高 如何得到+保存格式 yaml 保存文件格式: 1. ...
- http 错误代码
2xx 成功 200 正常:请求已完成. 201 正常:紧接 POST 命令. 202 正常:已接受用于处理,但处理尚未完成. 203 正常:部分信息 — 返回的信息只是一部分. ...
- 字节序(Endian),大端(Big-Endian),小端(Little-Endian)
http://www.cppblog.com/tx7do/archive/2009/01/06/71276.html 在各种计算机体系结构中,对于字节.字等的存储机制有所不同,因而引发了计算机通信领域 ...
- 多线程“尚未调用coinitialize” 报错
关于多线程中创建使用TADOConnect.TADODataSet等Com组件时,必须先初始化Com 在多线程启用执行前 CoInitialize(nil); 在多线程启用执行后 CoUninitia ...