【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);
}
posted @ 2022-05-17 01:40  HZX↑  阅读(502)  评论(0编辑  收藏  举报