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表达式的更多相关文章

  1. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  2. Java8 新特性学习 Lambda表达式 和 Stream 用法案例

    Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...

  3. 夯实Java基础(二十二)——Java8新特性之Lambda表达式

    1.前言 Java 8于14年发布到现在已经有5年时间了,经过时间的磨练,毫无疑问,Java 8是继Java 5(发布于2004年)之后的又一个非常最重要的版本.因为Java 8里面出现了非常多新的特 ...

  4. java8的新特性之lambda表达式和方法引用

    1.1. Lambda表达式 通过具体的实例去体会lambda表达式对于我们代码的简化,其实我们不去深究他的底层原理和背景,仅仅从用法上去理解,关注两方面: lambda表达式是Java8的一个语法糖 ...

  5. Java8学习笔记----Lambda表达式 (转)

    Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家       本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...

  6. JAVA8学习——深入浅出Lambda表达式(学习过程)

    JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...

  7. Java8特性之Lambda、方法引用以及Stream流

    Java 8 中的 Streams API 详解:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ Java笔记——Jav ...

  8. java8:(Lambda 表达式简介)

    JDK8的新特性——Lambda表达式 JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分 ...

  9. Java8新特性之Lambda表达式

    lambda表达式是java8给我们带来的几个重量级新特性之一,借用lambda表达式,可以让我们的java程序设计更加简洁.最近新的项目摒弃了1.6的版本,全面基于java8进行开发,本文是java ...

随机推荐

  1. Redis学习(1)——下载与配置[转]

    Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主 ...

  2. python移除系统多余大文件-乾颐堂

    文件多了乱放, 突然有一天发现硬盘空间不够了, 于是写了个python脚本搜索所有大于10MB的文件,看看这些大文件有没有重复的副本,如果有,全部列出,以便手工删除 使用方式 加一个指定目录的参数 比 ...

  3. Header add Access-Control-Allow-Origin: *

    允许所有域名跨域 Header add Access-Control-Allow-Origin: *

  4. list<?>转换成 对应的 class

    项目中用到的,list转换成bean.因为查询出来的数据用list 泛型接收,要返回 实体对象.所以需要对应转换. 主要用到的技术:反射. 上代码: public static <T> L ...

  5. [GO]非结构体匿名字段

    package main import ( "fmt" ) type mystr string //给一个类型重命名 type Person struct { name strin ...

  6. 特征工程 vs. 特征提取

    “特征工程”这个华丽的术语,它以尽可能容易地使模型达到良好性能的方式,来确保你的预测因子被编码到模型中.例如,如果你有一个日期字段作为一个预测因子,并且它在周末与平日的响应上有着很大的不同,那么以这种 ...

  7. jquery cookie用法

    jquery cookie用法(获取cookie值,删除cookie) cookie在jquery中有指定的cookie操作类,下面我先来介绍我们在使用cookie操作类时的一些问题,然后介绍正确的使 ...

  8. Maven整理笔记のMaven使用实践

    我们通过实践来补充Maven构建的生命周期. 第一步:配置POM 接着上一篇Maven使用,我们先创建一个名为helloworld的文件夹,在helloworld目录下创建pom.xml文件,pom. ...

  9. touch和click优先性

    jQuery的touch事件是当用户触摸事件(页面)时触发的. jQuery的click事件是当用户点击元素时触发的. 而事件执行流程是手指点击一个元素,会经过:touchstart --> t ...

  10. Transaction And Lock--两种方式实现可重复读

    一些需求要求两次查询数据之间不允许数据被修改,即可重复读取 可重复读REPEATABLE READ与串行化SERIALIZABLE的区别在于串行化要求满足该查询的数据不被修改且无新满足该查询条件的数据 ...