Java8与Scala中的λ表达式深入讲解

  

  

最近几年λ表达式风靡于编程界。很多现代编程语言都把它作为函数式编程的基本组成部分。基于JVM的编程语言如Scala中,Groovy及Clojure把它作为关键部分集成在语言中。而如今,(最终)Java 8也加入了这个有趣的行列。

  

Java8终于要支持λ表达式。自2009年以来λ表达式已经在λ项目中被支持。在那时候,λ表达式仍被称为Java闭包。在我们进入一些代码示例以前,先来解释下为什么λ表达式在Java程序员中广受欢迎。
  

  


  

  

λ表达式通常使用在图形用户界面(GUI)的开发中。一般来说,GUI编程将程序行为和事件做连接。比如,当用户按下一个按钮(触发一个事件),你的程序就需要去执行某些行为,可能是将一些数据储存到一个数据存储器中,在摇摆中,可以使用ActionListener来实现:
  

        类ButtonHandler实现ActionListener {   公共空间actionPerformed (ActionEvent e) {//做某事   }   }      类UIBuilder {   公共UIBuilder () {   按钮。addActionListener(新ButtonHandler ());   }   }      

这个例子表明了ButtonHandler类作为一个回调替换的用法。在这里ButtonHandler类仅包含ActionListener接口定义的actionPerformed方法。我们可以使用匿名内部类来简化代码:
  

        类UIBuilder {   公共UIBuilder () {   按钮。addActionListener(新ActionListener () {   公共空间actionPerformed (ActionEvent事件){//做某事   }   })   }   }      

这样代码简洁多了。更仔细的去看代码时,就会发现我们还创建一个只生成一个实例的类,而这个实例也仅仅持有一个独立的方法。这恰好是λ表达式所能解决的其中一类问题。
  

  


  

  

一个λ表达式从字面上讲就是一个函数。它定义了一个函数的输入参数和函数体8 . java中的,λ表达式语法尚未确定,不过大致应该类似这个样子的:
  

        (类型参数)→function_body      

一个具体的例子:
  

        字符串(字符串s1, s2)→s1.length ()——s2.length ();      

这个λ表达式用来计算两个字符串的长度差。还有一些扩展的语法,比如避免参数的类型定义(我们马上见看到例子)还有使用{和}来支持多行定义。
  

  

<代码> Collections.sort() 方法是λ表达的理想例子。它允许我们将字符串按照长度排序:
  

        List=数组列表。asList(“长”、“短”“小”);   集合。sort(列表,(琴弦s1, s2)→s1.length ()——s2.length ());   比;“小”、“短”,“看看”。      

所以,不像现在java必须要求的向一方法输入一个已经实现的比较器(比较器)而是传送一个λ表达式我们就可以得到相同的结果。
  

  


  

  

λ表达式有许多有趣的特性。其中之一是,它们是闭包。一个闭包允许函数访问直接词法作用域之外的变量。
  

        弦外=" java 8 "   (字符串s1)→s1.length ()——outer.length ()      

在例子中,λ表达式访问了字符串外这个作用域之外定义的变量。对于内联闭包来说这是很难做到的。
  

  


  

  

类型推论是java 7引入的但它同样适用于λ表达式。简单来说,类型推论意味着程序员可以在任意一个编译器能够自动推断出类型的地方省略类型定义。
  

  

如果类型推论能够应用到前面的排序λ表达式上,那么它就能写成下面的样子:
  

        List列表=arrays . aslist (…);   集合。排序(列表(s1, s2)→-s2.length s1.length () ());      

就像你所见到的一样,参数s1和s2的类型被省略了。因为编译器知道列表是一个字符串集合,它知道被用来作为比较器的λ表达式必定是相同的类型,因此,这个类型不需要显式地声明,即使你有这么做的自由。
  

  

类型推论的主要优势就是减少样板代码,如果编译器可以为我们识别类型,为什么我们必须自己定义它们。
  

  


  

  

我们来体会下,为何λ表达式和类型推论有助于简化我们前面所提到的回调例子:

Java8与Scala中的λ表达式深入讲解