Java Lambda表达式和示例
Java Lambda表达式是Java 8中最重要的功能之一。它是向Java编程语言中的函数式编程迈出的一步。该Java Lambda表达式教程概述了lambda表达式,例如什么是lambda表达式,如何编写表达式以及使用lambda表达式的优点是什么。
Java中的功能接口
在深入研究lambda表达式之前,我们应该了解Java中的功能接口。
功能接口是仅具有单个抽象方法(SAM)的接口。 Java中已经有很多功能接口(尽管Java 8中增加了许多新功能),例如具有单个run()方法的Runnable,具有call()方法的Callable或者具有compare()方法的Comparator。
要了解有关Java中的功能接口的更多信息,请参阅此职位Java中的功能接口
Java中的Lambda表达式
Java lambda表达式是功能接口的实现。它是功能接口的实例,我们编写的lambda表达式实现了功能接口的抽象方法。
让我们尝试举例说明一下。通常,当我们实现功能接口时,很可能会将其实现为匿名类。例如,如果我们必须实现比较器,则将其编写为匿名类,如下所示:
List<Integer> myList = Arrays.asList(4, 7, 1, 10, 8, 12); Collections.sort(myList, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } });
由于Comparator是功能性接口,因此它也可以实现为Lambda表达式。
Collections.sort(myList, (Integer o1, Integer o2)-> o2.compareTo(o1));
我们在这里应注意的一些重点
通过将功能接口实现为lambda表达式,代码更加紧凑。
如果我们看到Collections.sort()方法,则将完成的工作写成一个函数-(Integer o1,Integer o2)-> o2.compareTo(o1),它表示功能接口的实例,并且可以作为方法传递论据。那就是lambda表达式的优点之一,我们可以将功能作为参数传递给另一个方法。
箭头运算符或者Lambda运算符
Java lambda表达式引入了一个新的运算符->在Java中称为Arrow运算符。箭头运算符分为两个部分
左侧指定了lambda表达式所需的参数,如果没有参数,该参数也可以为空。
右侧是lambda主体,实际上是lambda表达式的代码。
因此,Java Lambda表达式的语法如下:
(type arg1, type arg2, ....) -> lambda body
可以从使用lambda表达式的上下文中推断出类型,因此我们无需明确指定参数的类型。
(arg1, arg2, ....) -> lambda body
如果我们考虑使用lambda表达式,我们已经写了
Java示例中的Lambda表达式
现在,当我们对功能接口以及如何编写lambda表达式有了一个很好的了解之后,让我们看看Java中更多的Lambda表达式示例。
1最简单的lambda表达式是不带参数的一个表达式,只是一个返回值,可以写为。
()-> 10;
这是使用此lambda表达式的类。
// Functional interface interface TestInterface{ int getValue(); } public class LambdaExample { public static void main(String[] args) { // assigning to functional interface reference TestInterface ref = () -> 10; System.out.println("Value- " + ref.getValue()); } }
输出:
Value- 10
我们在这里应注意的一些重要事项是
由于lambda表达式是功能接口的实例,因此可以使用此声明中的功能接口引用来引用它-TestInterface ref =()-> 10;
由于没有参数,因此箭头运算符的左侧只是空括号。
2A带参数的lambda表达式。
// Functional interface interface TestInterface{ String getValue(String str1, String str2); } public class LambdaExample { public static void main(String[] args) { // assigning to functional interface reference TestInterface ref = (String str1, String str2) -> str1 + " " + str2; System.out.println("Value- " + ref.getValue("Hello", "Lambda")); } }
输出:
Value- Hello Lambda
在这里,我们有一个带有两个String参数的lambda表达式。我们无需指定参数的类型,因为可以从使用的上下文中推断出这些参数的类型,因此这也是可以接受的
TestInterface ref = (str1, str2) -> str1 + " " + str2;
Lambda表达式作为方法参数
在开始的时候,我们已经看到了一个示例,其中Comparator实现作为lambda表达式作为方法参数传递。这是lambda表达式的特征之一。将功能视为方法参数。
如果我们有一个参数作为功能接口的方法,则可以将与该功能接口兼容的lambda表达式作为方法参数传递。
在下面的Java lambda表达式作为方法参数的示例中,存在一个具有Callable作为参数的方法调用。由于Callable是功能性接口,因此在调用invoke方法时会将与之兼容的lambda表达式作为参数传递。
import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class LambdaExample { public static void main(String[] args) { LambdaExample obj = new LambdaExample(); try { Future<String> f = obj.invoke(()->"Calling callable"); System.out.println("Value returned from callable- " + f.get()); }catch(Exception e) { System.out.println("Exception message- " + e.getMessage()); } } //Method with Callable(funtional interface) as parameter <T> Future<T> invoke(Callable<T> c) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); Future<T> f = executor.submit(c); executor.shutdown(); return f; } }
输出:
Value returned from callable- Calling callable
在Java中阻止Lambda表达式
到目前为止,我们所看到的都是单个表达式,但是我们也可以使用具有多个语句的lambda表达式,这些语句称为块lambda表达式。
在一个lambda表达式块中,用花括号将代码块括起来,并显式使用return返回值。
//Functional interface interface TestInterface{ String getValue(int i); } public class LambdaExample { public static void main(String[] args) { //block lambda TestInterface ref = (int i) -> { String s; if((i % 2) == 0) { s = "Even"; }else { s = "Odd"; } return s; }; int num = 5; System.out.println(num + " is- " + ref.getValue(num)); } }
输出:
5 is- Odd