技术开发 频道

Java 8中的Lambda表达式实现

  【IT168 评论】Lambda表达式是Java 8最受欢迎的特性。它们向Java中引入了函数式编程概念,这是一种完全面向对象的命令式编程语言。函数式编程语言的工作原理超出了本文的范围,但我将提取一个特性,这对使用OOP的人而言将是显而易见的。

Java 8中的Lambda表达式实现

  在这篇文章中,我们将了解lambda表达式是什么,以及如何适应整个Java生态系统。我们还将看看在不使用lambda表达式的情况下工作的示例代码,然后使用lambda重构此代码。

  了解Lambda表达式

  如果你熟悉Groovy或者Ruby这些支持Lambda表达式的编程语言,那么你一开始可能会认为Java的Lambda表达式并不像其他编程语言中的那样简洁。在java中,Lambda表达式是SAM类型,SAM类型是一个具有单一抽象方法的接口。

  Lambda表达式在运行期表示为一个函数接口(functionalinterface)(或者说一个SAM类型),函数接口是一种只定义了一个抽象方法的接口。尽管JDK已经有一些接口都符合函数接口定义,比如Runnable 和 Comparator,但是这对API演进来说是显然不够的。

  Lambda表达式是一个可以执行传递的代码块。将一个代码块传递给函数是Java程序员不习惯的东西。我们所有定义代码的行为都封装在方法体中,并通过对象引用执行:

Java 8中的Lambda表达式实现

  这是调用隐藏方法实现的经典OOP风格。 调用者只是将一个变量传递给方法,然后用变量的值做一些事情,并返回另一个值或产生一个副作用。

  我们现在将使用除了变量传递之外的等效实现的行为传递。要实现这一点,必须创建一个接口,定义抽象行为,而不是方法。该接口是只有一种方法的接口:

Java 8中的Lambda表达式实现

  在上述实现中,打印机接口负责所有打印。方法print Something不定义行为,而是执行由Printer定义的行为:

Java 8中的Lambda表达式实现

  你们可能注意到没有新的东西。这是真的,因为还没有应用lambda表达式。简单地创建一个具体的打印机接口实现,并将其传递给print Something方法。

  以上演示旨在达到在Java中引入Lambda表达式的关键目标:

  lambda表达式主要用于定义函数接口的内联实现。

  在我们使用lambda表达式重构上面的例子之前,要学习一些必要的语法:

Java 8中的Lambda表达式实现

  lambda有逗号分隔,括号括起来的形式参数列表,我们将在方法声明中定义,后跟一个箭头标记指向要执行的代码。现在重构上面的代码来使用lambda:

Java 8中的Lambda表达式实现

  非常紧凑和美观,由于函数接口只声明一个方法,在lambda的第一部分传递的参数被自动映射到方法参数列表,箭头右边的代码被视为方法具体实现。

  为什么使用Lambda表达式

  与上一节中的演示相同,lambda表达式使我们能够拥有更加简洁的代码,更容易阅读和跟踪。 还有与性能和多核处理一致的其他好处,但它们只有在理解Streams API之后才有意义。

  比较具有和不具有lambda的方法实现确实缩短了代码,显示了lambda表达式的力量:

Java 8中的Lambda表达式实现

  我们可以使我们的代码比这更简洁。这样,即使没有在箭头的左边指定参数类型,它的类型也将可以由编译器从接口方法的形式参数推断:

Java 8中的Lambda表达式实现

  lambdas的另一个特征是:如果只有一个参数,我们可以完全消除括号。同样,如果箭头右侧只有一个语句,我们也可以删除大括号:

Java 8中的Lambda表达式实现

  现在代码看起来很可爱,如果接口方法没有接受任何参数,可以用空圆括号替换声明:

Java 8中的Lambda表达式实现

  我们只是内联lambda,而不先创建一个对象,然后将它传递给thesaySomething方法:

Java 8中的Lambda表达式实现

  现在开始谈论函数式编程。我们最初的9行现在只有3行。这种紧凑的代码使得lambda表达式对Java程序员非常有吸引力。

  结论

  本文对Java中的Lambda表达式进行了简单介绍,并了解了如何使用它们来提高接口实现的代码质量。 但lambda的所有魅力并没有在本文中全部展现出来,一旦开发者认识到像Lambda这些特性有益于提升开发效率,那么我们将会看到Lambda表达式更广泛的应用。

1
相关文章