Java Lambda表达式和示例

时间:2020-01-09 10:35:13  来源:igfitidea点击:

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