【Java8新特性】 Lambda表达式

一、Lambda 表达式 是什么?

Lambda读音:拉姆达。

  • Lambda是一个匿名函数,匿名函数就是一个没有名字的函数。
  • Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
  • Lambda 表达式可以使代码变的更加简洁紧凑

语法

lambda 表达式的语法格式如下:

(parameters) -> expression 或 (parameters) ->{ statements; } 

Java8 中引入了一个新的操作符 ->, 该操作符称为箭头操作符或 Lambda 操作符。

箭头操作符将 Lambda 表达式拆分成两部分:

左侧 : Lambda 表达式的参数。

右侧 : Lambda 表达式中所需执行的操作, 即 Lambda 体。

lambda表达式的重要特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体只有一个语句,可以不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

二、Lambda 表达式实例

Lambda 表达式的简单例子:

// 1. 无参数,无返回值 () -> System.out.print(Hello Lambda);  // 2. 无参数,有返回值,返回值 5 () -> 5;    // 3. 一个参数(箭头左侧括号可以省略),返回“参数+1”后的值 x -> x + 1  // 4. 两个参数(多个参数时,箭头左侧括号不可以省略),返回它们的差值 (x, y) -> x - y      // 5. 三个int型整数(支持多个参数),返回它们的和 (int x, int y, int z) -> x + y + z    // 6. 接收一个 string 对象,并在控制台打印,不返回任何值(大括号可以省略) (String s) -> System.out.print(s) 或 (String s) -> { System.out.print(s); }  

注 : Lambda 表达式中的参数类型都是由编译器推断得出的。 Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。 Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的,这就是所谓的 “类型推断”。

三、函数式接口(function interface)

Lambda 表达式需要 “函数式接口” 的支持。

函数式接口 : 接口中只有一个抽象方法的接口,称为函数式接口,可以通过 Lambda 表达式来创建该接口的对象。

可以使用 @FunctionalInterface 注解来检查该接口是否为函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口,可以有效避免其它开发人员在该接口中新增额外的方法。

简单示例

接口:

//自定义函数式接口 @FunctionalInterface public interface MyFun {     void run(); }  

应用:

public static void main(String[] args) {    //jdk8之前 	testMyFun(new MyFun() {     @Override     public void run() {       System.out.println(这是自定义函数接口);     }   });      //java8使用lambada表达式,代码更简洁   testMyFun(() -> System.out.println(这是自定义函数接口)); }  private void testMyFun(MyFun myFun) {   myFun.run(); } 

四、java8四大内置核心函数式接口

java8为我们定义好了4类内置函数式接口,这4类接口基本能够满足平时的开发需要,如果有比较特殊的情况我们可以自己去定义函数式接口。

1、consumer 消费型接口,有入参,没有返回值

@FunctionalInterface public interface Consumer<T> {       /**      * Performs this operation on the given argument.      *      * @param t the input argument      */     void accept(T t); } 

应用示例:

public static void main(String[] args) {    	consumTest(1000,x-> System.out.println(消费了:+x+元));    }   public void consumTest(int money, Consumer consumer){ 	consumer.accept(money); } 

2、Supplier 提供型接口,空参,有返回值

@FunctionalInterface public interface Supplier<T> {      /**     * Gets a result.     *     * @return a result     */    T get(); } 

应用示例:

public static void main(String[] args) {    	int i = supplyTest(() -> (int) (Math.random() * 10););         	System.out.println(获得的随机数是:+i);    }   public int supplyTest(Supplier<Integer> supplier){   return supplier.get(); } 

3、Function<T, R> 函数型接口,有入参,有返回值

@FunctionalInterface public interface Function<T, R> {       /**      * Applies this function to the given argument.      *      * @param t the function argument      * @return the function result      */     R apply(T t); } 

应用示例:计算一个数的2倍,并输出结果

public static void main(String[] args) {    	int num = functionTest(5, x -> x * 2); 	System.out.println(计算后的结果值是:+num);    }           public int functionTest(int a,Function<Integer,Integer> function){   return function.apply(a); } 

4、Predicate 断言型接口,返回真假

@FunctionalInterface public interface Predicate<T> {       /**      * Evaluates this predicate on the given argument.      *      * @param t the input argument      * @return {@code true} if the input argument matches the predicate,      * otherwise {@code false}      */     boolean test(T t); } 

应用示例:判断一个数是否大于10,并输出真假

public static void main(String[] args) {        	boolean flag = predicateTest(20, x -> x > 10); 	System.out.println(20比10大吗:+ flag);     }  public boolean predicateTest(int x,Predicate<Integer> predicate){   return  predicate.filter(x); }