现在的位置: 首页 > 编程语言 > 正文

为什么使用Lambda表达式?Scala中的Lambda表达式是什么

2020年06月05日 编程语言 ⁄ 共 2906字 ⁄ 字号 评论关闭

  Java8终于要支持Lambda表达式!自2009年以来Lambda表达式已经在Lambda项目中被支持。在那时候,Lambda表达式仍被称为Java闭包。下面学步园小编来讲解下为什么使用Lambda表达式?Scala中的Lambda表达式是什么?

  为什么使用Lambda表达式

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

  classButtonHandlerimplementsActionListener{

  publicvoidactionPerformed(ActionEvente)

  {

  //dosomething

  }

  }

  classUIBuilder{

  publicUIBuilder(){

  button.addActionListener(newButtonHandler());

  }

  }

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

  classUIBuilder{

  publicUIBuilder(){

  button.addActionListener(newActionListener(){

  publicvoidactionPerformed(ActionEventevent){

  //dosomething

  }

  })

  }

  }

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

  Lambda表达式代替函数

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

  (typeparameter)->function_body一个具体的例子:

  (Strings1,Strings2)->s1.length()-s2.length();

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

  Collections.sort()

  方法是lambda表达的理想例子。它允许我们将字符串按照长度排序:

  Listlist=Array.asList("loooooong","short","tiny");

  Collections.sort(list,(Strings1,Strings2)->s1.length()-s2.length());

  >"tiny","short","loooooong".

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

  Lambda表达式代替闭包

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

  Stringouter="java8"(Strings1)->s1.length()-outer.length()

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

  Lambda表达式也支持类型推论

  类型推论是java7引入的但它同样适用于lambda表达式。简单来说,类型推论意味着程序员可以在任意一个编译器能够自动推断出类型的地方省略类型定义。如果类型推论能够应用到前面的排序lambda表达式上,那么它就能写成下面的样子:

  Listlist=Arrays.asList(…);

  Collections.sort(list,(s1,s2)->s1.length()-s2.length());

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

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

  珍爱Lambda表达式,远离匿名内部类

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

  classUIBuilder{

  publicUIBuilder(){

  button.addActionListener(e->//processActionEvente)

  }

  }

  我们下载直接传送一个lambda表达式进入addActionListener方法来代替前面定义的持有回调方法的类。除了减少模板代码和提高可读性以外,它使我们直接表达我们唯一感兴趣的事情:处理事件。

  在我们了解lambda表达式更多优势之前,先来看看在Scala中的lambda表达式副本。

  Scala中的Lambda表达式是什么

  在函数式编程中,函数是基本的构造块。Scala融合了java中的面向对象编程和函数式编程。在Scala中,一个lambda表达式是种叫做"函数"或者"函数文本".Scala中的函数属于一等公民。它们可以被分配给vals或者vars(最终变量或者非最终变量),它们可以作为其他函数的参数,也可以组合成新的函数。

  在Scala中一个函数文本写成如下形式:

  (argument)=>//funtionbody

  举例来说,前面提到的java用来计算两个字符串长度差的lambda表达式,在Scala中写作如下:

  (s1:String,s2:String)=>s1.length-s2.

  lengthScala中的函数文本也是闭包。它可以访问在直接词法作用域之外定义的变量。

  valouter=10valmyFuncLiteral=(y:Int)=>y*outervalresult=myFuncLiteral(2)>20这个例子结果是20.

  正如你所见,我们将函数文本分配给了变量myFuncLiteral.

  java8的lambda表达式和Scala的函数文本在语法和语义上的相似性是十分明显的。从语义上讲它们是相同的,而语法上的唯一不同就是箭头符号(java8->,scala=>)和我们没有提到的简化符号。

  以上就是关于“为什么使用Lambda表达式?Scala中的Lambda表达式是什么”的内容,希望对大家有用。更多资讯请关注学步园。学步园,您学习IT技术的优质平台!

抱歉!评论已关闭.