JAVA8系列教程-Lambda表达式
Java lambda表达式是Java 8附带的一个非常令人兴奋的新功能。对于我们许多使用scala之类的高级语言工作的人来说,它们并不陌生。
实际上,如果您回顾历史并尝试找出过去20年中Java语言的任何改进,您将无法回忆起许多令人兴奋的事情。在过去的十年中,java中只有很少的并发类,泛型,如果您也同意,那么注释也是如此。Lambda表情打破了这种干旱,感觉就像是一件令人愉快的礼物。
在本文中,我将分三部分介绍lambda表达式及其概念。以下是继续进行的计划。
1. Java中的lambda表达式是什么?
在编程中,Lambda表达式(或函数)只是一个匿名函数,即不带名称且不受标识符限制的函数。
Lambda表达式的最重要特征是它们在外观上下文中执行。因此,相似的lambda表达式可以在其他上下文中以不同的方式执行(即逻辑相同,但基于传递给函数的不同参数,结果将有所不同)。
上面的定义充满了关键字,只有当您已经深入了解什么是lambda表达式时才能理解。因此,一旦您对下一部分中的lambda表达式有了更好的了解,我建议您重新阅读以上段落。
因此,很明显lambda是某种没有名称和标识符的函数。好吧,有什么大不了的?为什么每个人都这么兴奋?
答案在于,与面向对象编程(OOP)相比,功能编程所带来的好处。大多数OOP语言围绕对象和实例发展,并且仅将它们作为头等公民对待。另一个重要的实体,即职能重新占了上风。这在Java中尤其如此,在Java中,函数不能存在于对象外部。函数本身在Java中没有任何意义,直到它与某个对象或实例相关为止。
但是在函数式编程中,您可以定义函数,为它们提供引用变量并将其作为方法参数传递等等。JavaScript是一个很好的例子,您可以将回调方法(例如)传递给Ajax调用。它是非常有用的功能,并且从一开始就缺少Java。现在使用Java 8,我们也可以使用这些lambda表达式。
1.1 Lambda语法
典型的lambda表达式语法如下所示:
(x, y) -> x + y //This function takes two parameters //and return their sum. |
现在基于x和y的类型,可以在多个地方使用方法。参数可以匹配int或Integer或简单地也可以匹配String。根据上下文,它将添加两个整数或连接两个字符串。
句法:
lambda表达式的其他可能语法为:
either (parameters) -> expression //1 or (parameters) -> { statements; } //2 or () -> expression //3 |
1.2 Lambda示例
让我们也看一下lambda表达式的一些示例:
( int a, int b) -> a * b // takes two integers and returns their multiplication (a, b) -> a - b // takes two numbers and returns their difference () -> 99 // takes no values and returns 99 (String a) -> System.out.println(a) // takes a string, prints its value to the console, and returns nothing a -> 2 * a // takes a number and returns the result of doubling it c -> { //some complex statements } // takes a collection and do some procesing |
1.3 Lambda表达式的功能
让我们确定lambda表达式的一些功能:
- Lambda表达式可以具有零个,一个或多个参数。
- 参数的类型可以显式声明,也可以从上下文中推断出来。
- 多个参数用强制括号括起来,并用逗号分隔。空括号用于表示空参数集。
- 当有单个参数时,如果推断出其类型,则不强制使用括号。例如a->返回a * a。
- Lambda表达式的主体可以包含零个,一个或多个语句。
- 如果lambda表达式的主体具有单个语句,则不必使用大括号,并且匿名函数的返回类型与主体表达式的返回类型相同。如果正文中的陈述多于一个,则这些陈述必须用大括号括起来。
因此,我们简要了解了什么是lambda表达式。如果您感到迷茫且无法联系,请耐心等待,如何在Java编程语言中使用它。我们将在接下来的30分钟内解决所有问题。因此,让我们开始吧。
在深入研究lambda表达式和Java编程之间的关系之前,您还必须了解功能接口。这太重要了。
2. Java 8 Functional接口
Single Abstract Method interfaces (SAM接口)不是一个新概念。这意味着接口只能有单一的方法。在Java中,我们已经有许多此类SAM接口的示例。从Java 8开始,它们也将被称为功能接口。Java 8通过使用新的注解@FunctionalInterface标记这些接口来实施单一职责规则。
例如,Runnable接口的新定义是这样的:
@FunctionalInterface public interface Runnable { public abstract void run(); } |
如果尝试在任何功能接口中添加新方法,则编译器将不允许您执行此操作,并且会引发编译时错误。
到目前为止,一切都很好。但是,它们与Lambda表达式有何关系?让我们找出答案。
我们知道Lambda表达式是不带名称的匿名函数,它们(大多数)作为参数传递给其他函数。好吧,在Java方法中,参数总是具有类型,并且在确定方法重载甚至是简单方法调用的情况下,都会寻找此类型信息以确定需要调用哪个方法。因此,基本上每个lambda表达式也必须都可以转换为某种类型才能被接受为方法参数。嗯,转换lambda表达式的类型始终是函数接口类型。
让我们通过一个例子来理解它。如果我们必须编写一个在控制台上打印“ howtodoinjava”的线程,那么最简单的代码将是:
new Thread( new Runnable() { @Override public void run() { System.out.println( "howtodoinjava" ); } }).start(); |
如果我们使用lambda表达式执行此任务,则代码将为:
new Thread( () -> { System.out.println( "My Runnable" ); } ).start(); |
我们还看到Runnable是具有单个方法run()的功能接口。因此,当您将lambda表达式传递给Thread类的构造函数时,编译器将尝试将该表达式转换为等效的Runnable代码,如第一个代码示例所示。如果编译器成功,则一切运行良好,如果编译器无法将表达式转换为等效的实现代码,它将抱怨。在此,在上面的示例中,lambda表达式被转换为Runnable类型。
3. Java 8 lambda表达式示例
我列出了一些代码示例,您可以阅读并分析如何在日常编程中使用lambda表达式。
1)遍历一个List并执行一些操作
List<String> pointList = new ArrayList(); pointList.add( "1" ); pointList.add( "2" ); pointList.forEach(p -> { System.out.println(p); //Do more work } ); |
2)创建一个新的可运行对象并将其传递给线程
new Thread( () -> System.out.println( "My Runnable" ); ).start(); |
3)按员工对象的名称对其进行排序
public class LambdaIntroduction { public static void main (String[] ar){ Employee[] employees = { new Employee( "David" ), new Employee( "Naveen" ), new Employee( "Alex" ), new Employee( "Richard" )}; System.out.println( "Before Sorting Names: " +Arrays.toString(employees)); Arrays.sort(employees, Employee::nameCompare); System.out.println( "After Sorting Names " +Arrays.toString(employees)); } } class Employee { String name; Employee(String name) { this .name = name; } public static int nameCompare(Employee a1, Employee a2) { return a1.name.compareTo(a2.name); } public String toString() { return name; } } Output: Before Sorting Names: [David, Naveen, Alex, Richard] After Sorting Names [Alex, David, Naveen, Richard] |
4)将事件侦听器添加到GUI组件
JButton button = new JButton( "Submit" ); button.addActionListener((e) -> { System.out.println( "Click event triggered !!" ); }); |
上面是Java 8中lambda表达式的非常基本的示例。我将不时提出一些更有用的示例和代码示例。
- 本文标签: 其他
- 本文链接: https://www.v8en.com/article/240
- 版权声明: 本文由SIMON原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权