java8 您所在的位置:网站首页 标准名称的三个部分是什么 java8

java8

2024-06-15 04:45| 来源: 网络整理| 查看: 265

前面的文章中已经多次出现了Lambda表达式的身影,其简洁与灵活性相信读者也应有所感受。那么Lambda表达式究竟是个什么鬼?它的语法是什么?它由什么组成?我们该怎样使用Lambda表达式以及在哪里使用?本篇文章将解答这些问题。

Lambda表达式是什么?

可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。

匿名——我们说匿名,是因为它不像普通的方法那样有一个明确的名称:写得少而想得多!函数——我们说它是函数,是因为Lambda函数不像方法那样属于某个特定的类。但和方法一样, Lambda有参数列表、函数主体、返回类型,还可能有可以抛出的异常列表。传递——Lambda表达式可以作为参数传递给方法或存储在变量中。简洁——无需像匿名类那样写很多模板代码。

Lambda表达式的语法与组成

Lambda表达式由参数、箭头、主体组成。如下图:

Lambda表达式的组成

参数列表——这里它采用了Comparator中compare方法的参数,两个Apple。箭头——箭头->把参数列表与Lambda主体分隔开。Lambda主体——比较两个Apple的重量。表达式就是Lambda的返回值了。

所以,Lambda表达式的基本语法可以总结为:(parameters) -> expression 或 (parameters) -> { statements; }

对照上面的语法,下表列出了一些常用的Lambda表达式:

使用案例Lambda示例布尔表达式(List list) -> list.isEmpty()创建对象() -> new Apple(10)消费一个对象(Apple a) -> {System.out.println(a.getWeight());}从一个对象中选择/抽取(String s) -> s.length()组合两个值(int a, int b) -> a * b比较两个对象(Apple a1, Apple a2) ->a1.getWeight().compareTo(a2.getWeight())

Lambda表达式的使用

在前面文章中那个过滤苹果的方法,我们用Lambda表达式实现的如下:

  List greenApples = filter(inventory, (Apple a) -> "green".equals(a.getColor()));

那么为什么能这样使用呢?filter方法的第二个参数实际上是一个函数式接口Predicate,它的定义如下:

  public interface Predicate{boolean test (T t);}

函数式接口就是只定义一个抽象方法的接口

实际上,在java8以前,我们可能已经接触过下面这些函数式接口:

  //java.util.Comparatorpublic interface Comparator {int compare(T o1, T o2);}//java.lang.Runnablepublic interface Runnable{void run();}//java.awt.event.ActionListenerpublic interface ActionListener extends EventListener{void actionPerformed(ActionEvent e);}//java.util.concurrent.Callablepublic interface Callable{V call();}//java.security.PrivilegedActionpublic interface PrivilegedAction{V run();}

而Predicate是java8中定义的一个新的函数式接口.

Lambda表达式允许我们以内联的方式实现一个函数式接口(Lambda表达式本身就是函数式接口的一个实例).

如下,我们即可以以函数式接口的方式,也可以以匿名类的方式传递runnable的实体,它们的实现效果相同,只是匿名类更为烦锁而已:

  //使用Lambda实例化runnableRunnable r1 = () -> System.out.println("Hello World 1");//使用匿名类,实例化runnableRunnable r2 = new Runnable(){public void run(){System.out.println("Hello World 2");}};public static void process(Runnable r){r.run();}process(r1);process(r2);//直接传递Lambda表达式process(() -> System.out.println("Hello World 3"));

从上面的代码中可以看出,Lambda表达式可以赋值给一个变量,也可以作为参数直接传递给以函数式接口为参数的方法,前提是Lambda表达式的签名要和函数式接口的抽象方法一样,这个抽象方法也叫做函数描述符,java编译器就是根据上下文来匹配函数描述符来判断Lambda表达式是否合法.

Lambda表达式在环绕执行模式(execute around)中的应用

通俗来讲,环绕执行模式(execute around)是指代码执行的首尾都是模版代码,真正重要的代码在中间部分执行,比如文件处理:先是打开文件,然后对文件进行处理,最后释放资源,这里我们关注的重点是对文件的处理,而不是打开文件与资源的释放.

而文件的处理,因为需求的不同会有所区别,所以Lambda表达式特别适合环绕执行模式的代码开发,像打开文件与释放资源这种一成不变的模版代码写在方法内,不同需求对应的不同行为以Lambda的形式传递进去。

代码如下:

  //定义函数式接口来传递处理文件的行为@FunctionalInterfacepublic interface BufferedReaderProcessor {String process(BufferedReader b) throws IOException;}//定义处理文件的方法(环绕执行模式)public static String processFile(BufferedReaderProcessor p) throws IOException {try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {return p.process(br);}} //传递Lambda:读取一行String oneLine = processFile((BufferedReader br) -> br.readLine()); //传递Lambda:读取两行String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有