Java8新特性——Lambda表达式(一)

1. 预备知识

在了解Lambda表达式之前首先需要了解以下预备知识。

1.1 如何成为一名高级码农?

如果老板让你写一个用于毁灭地球的函数,而你写了一个毁灭行星的函数,若要毁灭地球只需将毁灭地球的过程传递给“毁灭行星”。能做到这一点,你就是一名高级码农。

以上这个问题体现了程序可扩展性的思想。总结一下,要成为一名高级码农,在编码的时候要以发展的眼光看待问题。一个具体问题到来的时候,你需要基于当前问题抽象出解决这一类问题的办法,那么当相似的问题到来时,你只需花少量的时间就能完成任务,而且避免了代码复制,降低了bug的风险。

1.2 实现程序可扩展性的例子

在Java8以前,要实现程序的可扩展性,我们常用匿名内部类传递用于扩展的代码,举个例子:

实现一个能从List集合中筛选指定对象的函数filter。 1. 若List中存放Person对象,要求筛选出30岁以上的Person 2. 若List中存放Apple,要求筛选出红色的Apple

使用匿名内部类的解决方案:

  • 实现filter函数
List<T> filter(List<T> list, FilterProcessor filterProcessor){
    List<T> result = new ArrayList<T>();
    for(T t : list){
        if(filterProcessor.process(t))
            result.add(t);
    }
    return list;
}
  • 定义FilterProcessor接口
interface FilterProcessor<T>{
    boolean process(T);
}
  • 使用匿名内部类实现筛选出30岁以上的Person
List<Person> result = filter(list, new FilterProcessor<Person>(){
    boolean process(Person person){
        if(person.getAge()>=30)
            return true;
        return false;
    }
});
  • 使用匿名内部类筛选出红色的Apple
List<Apple> result = filter(list, new FilterProcessor<Apple>(){
    boolean process(Apple apple){
        if(apple.getColor().equals("red"))
            return true;
        return false;
    }
});

若要增加新的筛选规则,只需给filter函数传递新的匿名内部类即可。程序具有了可扩展性,恭喜你已经成为一名高级码农!

1.3 什么是“策略模式”?

上述过程总结来说,当我们需要解决同一类问题的时候,若发现这类问题大部分处理过程是一致的,只是核心步骤存在差异,这时候就可以使用上述方式:先把函数相同的部分写好,再抽象出一个接口,不同部分的代码放在接口的实现类中。要使用时,只需将实现类的对象传递给该函数即可。 这种方式在设计模式中称为“策略模式”。

1.4 使用匿名内部类实现策略模式的弊端?

使用匿名内部类实现策略模式代码比较冗余,不易阅读,就像这样:

List<Apple> result = filter(list, new FilterProcessor<Apple>(){
    boolean process(Apple apple){
        if(apple.getColor().equals("red"))
            return true;
        return false;
    }
});

Java8提出了Lambda表达式,它是实现策略模式的另外一种方式,目的就是为了使代码简单清晰。 使用Lambda表达式实现相同功能:

List<Apple> result = filter(list, (Apple apple)—>apple.getColor().equals("red"));

这样是不是简单多了!Lambda表达式本质上是将一个函数的代码作为一个参数或变量进行传递,这种处理方式有个专门的名字——函数式编程。

1.5 什么是函数式编程?

所谓“函数式”编程,就是将函数的代码当作一个变量,传递给另一个变量或传递给一个函数,这种编程方式就称为“函数式编程”。 Java8中采用Lambda表达式实现函数式编程,它是策略模式的第二种实现方式,目的就是简化策略模式的代码实现。

2. Lambda表达式的语法

Lambda表达式用于表示一个函数,所以它和函数一样,也拥有参数、返回值、函数体,但它没有函数名,所以Lambda表达式相当于一个匿名函数。语法如下:

(Person person)—>person.getAge()>30

Lambda表达式用—>连接,->左侧为函数的参数,->右侧为函数体。 若右侧由多条语句构成则需要用{}包裹,如:

(Person person)—>{person.getAge()>30;System.out.println(person.getName());}

Lambda表达式无需显示指定返回值类型,JVM会根据->右侧语句的返回结果自动判断返回值类型,如:

(Person person)—>person.getAge()>30 #自动判断返回值为boolean型

3. 如何使用Lambda表达式?

仍以筛选年龄大于30的Person对象为例:

3.1 为Lambda表达式定义函数式接口

@FunctionalInterface
interface FilterProcessor<T>{
    boolean process(T t);
}

PS:该接口只能有一个抽象函数!接下来Lambda表达式就是该抽象函数的实现。 PS:在为Lambda表达式定义函数式接口时,需要加上注解@FunctionalInterface,这样当该接口中抽象函数个数不是1时就会报错提示。

3.2 实现筛选函数

List<T> filter(List<T> list, FilterProcessor<T> filterProcessor){
    List<T> result = new ArrayList<T>();
    if(filterProcessor.process(t))
        result.add(t);
    return result;
}

filter函数接收一个函数式接口,该参数用于接收一个Lambda表达式。

3.3 传递Lambda表达式

List<Person> result = filter(list, (Person p)->p.getAge()>30);

直接将Lambda表达式作为参数传递给filter的函数式接口即可,从而在result中就能获取年龄超过30岁的Person对象。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java技术学习之道

深入理解 Java 中的 Lambda

1212
来自专栏Java3y

插入排序就这么简单

插入排序就这么简单 从上面已经讲解了冒泡和选择排序了,本章主要讲解的是插入排序,希望大家看完能够理解并手写出插入排序的代码,然后就通过面试了!如果我写得有错误的...

4498
来自专栏工科狗和生物喵

【计算机本科补全计划】C++ Primer:指针和const限定符

正文之前 今天下午看了一下午的计算机组成与设计,结果好死不死的看到了设计部分--处理器的设计。天哪,我现在还只是一个准备给人装一台电脑做实验田的家伙,连用都不咋...

2754
来自专栏算法修养

C# 编码规范

将面向对象设计,也就是解耦,融入于编码之中。不要硬编码,要让你的代码扩展起来十分方便。

961
来自专栏技术小站

深入理解Java的接口和抽象类(转)

  对于面向对象编程来说,抽象是它的一大特征之一。在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。很...

702
来自专栏Play & Scala 技术分享

为Play初学者准备的Scala基础知识

3376
来自专栏编程

自学Python笔记(二)

作为最最基础的初学者,尤其是面对中小学生学习Python我想大概了解一下Python,能编个小程序,能看懂一般的程序就可以,如果想深一步的学习还是需要静下心来好...

2037
来自专栏醒者呆

融会贯通——深入了解面向对象设计原则“依赖倒转原则”

一千个人眼里有一千个哈姆雷特,下面我尝试用深入浅出的语言贯穿到“控制反转”,“依赖注入”,“面向抽象编程”,以及“面向接口编程”这几个概念。 传递参数,关联(组...

3367
来自专栏xingoo, 一个梦想做发明家的程序员

合并排序

分治算法: 用分治策略实现n个元素进行排序的方法。 基本思想: 将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终排好序的子集合合并成所要...

2069
来自专栏Python小屋

Python标准库collections中与字典有关的类

Python标准库中提供了很多扩展功能,大幅度提高了开发效率。这里主要介绍OrderedDict类、defaultdict类和Counter类。 (1)Orde...

2766

扫码关注云+社区