【核心笔记】 Lambda 表达式

       Lambda 表达式是 Java 8 引入的一个重要特性,它提供了一种简洁的方式来表达单个方法的接口,通常用于化代码中的匿名内部类。Lambda 表达式使得编写更简洁、可读性更高的代码成为可能,特别是在处理集合或多线程时。

1. Lambda 表达式的基本语法

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

        parameters 是参数列表,expression 或 { statements; } 是Lambda 表达式的主体。如果只有一个参数,可以省略括号;如果没有参数,也需要空括号。

        例如,我们定义一个函数,用于计算两个两个变量的和。

// 使用 Lambda 表达式计算两个数的和
MathOperation addition = (a, b) -> a + b;

// 调用 Lambda 表达式
int result = addition.operation(5, 3);
System.out.println("5 + 3 = " + result);

        在函数addition中,我们传入了两个参数a,b,返回这两个参数之和。

2.Lambda 表达式的使用场景

        Lambda 表达式主要用于函数式接口,即接口中只有一个抽象方法的接口。Java 内置了一些常用的函数式接口,如:

  • java.util.function.Predicate<T>:用于条件判断
  • java.util.function.Consumer<T>:用于执行某些操作
  • java.util.function.Function<T, R>:用于转换操作
  • java.util.function.Supplier<T>:用于提供对象

3.常用场景示例

1)使用 Lambda 替代匿名内部类

// 传统匿名内部类方式
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from traditional Runnable!");
    }
};

// Lambda 表达式方式
Runnable r2 = () -> System.out.println("Hello from Lambda Runnable!");

r1.run();  // 输出:Hello from traditional Runnable!
r2.run();  // 输出:Hello from Lambda Runnable!

2)用于集合的迭代

import java.util.Arrays;
import java.util.List;

public class LambdaExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // 传统方式
        for (String name : names) {
            System.out.println(name);
        }

        // 使用 Lambda 表达式
        names.forEach(name -> System.out.println(name));
    }
}

3)使用函数式接口

import java.util.function.Predicate;

public class LambdaWithPredicate {
    public static void main(String[] args) {
        Predicate<String> isLongerThanFive = (str) -> str.length() > 5;

        System.out.println(isLongerThanFive.test("Hello"));  // 输出:false
        System.out.println(isLongerThanFive.test("Hello World"));  // 输出:true
    }
}

4)Stream API 与 Lambda

import java.util.Arrays;
import java.util.List;

public class LambdaStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);

        // 使用 Lambda 表达式和 Stream API 过滤和操作集合
        numbers.stream()
               .filter(num -> num % 2 == 0)  // 过滤出偶数
               .map(num -> num * 2)  // 将每个偶数乘以2
               .forEach(num -> System.out.println(num));  // 输出结果
    }
}

4.Lambda表达式特征

1)简洁性

        Lambda 表达式提供了一种更为简洁的语法,尤其适用于函数式接口。相比于传统的匿名内部类,Lambda 表达式使得代码更为紧凑,减少了样板代码的编写。

2)函数式编程支持

        Lambda 表达式是函数式编程的一种体现,它允许将函数当作参数传递给方法,或者将函数作为返回值,这种支持使得 Java 在函数式编程方面更为灵活,能够更好地处理集合操作、并行计算等任务。

3)变量捕获

        Lambda 表达式可以访问外部作用域的变量,这种特性称为变量捕获,Lambda 表达式可以隐式地捕获 final 或事实上是 final 的局部变量。

4)方法引用

        Lambda 表达式可以通过方法引用进一步简化,方法引用允许你直接引用现有类或对象的方法,而不用编写冗余的代码。

5)可并行性

        Lambda 表达式能够更方便地实现并行操作,通过使用 Stream API 结合 Lambda 表达式,可以更容易地实现并行计算,提高程序性能。

5.Lambda 表达式的局限性

1)调试困难:由于简洁性,Lambda 表达式有时不易调试,尤其在大规模代码中。

2)不适合复杂逻辑:Lambda 表达式适合简单的逻辑操作,过于复杂的代码可能会降低可读性。

6. Lambda 表达式使用示例

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)
public class Java8Tester {
   public static void main(String args[]){
      Java8Tester tester = new Java8Tester();
        
      // 类型声明
      MathOperation addition = (int a, int b) -> a + b;
        
      // 不用类型声明
      MathOperation subtraction = (a, b) -> a - b;
        
      // 大括号中的返回语句
      MathOperation multiplication = (int a, int b) -> { return a * b; };
        
      // 没有大括号及返回语句
      MathOperation division = (int a, int b) -> a / b;
        
      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));
        
      // 不用括号
      GreetingService greetService1 = message ->
      System.out.println("Hello " + message);
        
      // 用括号
      GreetingService greetService2 = (message) ->
      System.out.println("Hello " + message);
        
      greetService1.sayMessage("Runoob");
      greetService2.sayMessage("Google");
   }
    
   interface MathOperation {
      int operation(int a, int b);
   }
    
   interface GreetingService {
      void sayMessage(String message);
   }
    
   private int operate(int a, int b, MathOperation mathOperation){
      return mathOperation.operation(a, b);
   }
}

7.注意事项

        Lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。但是可以直接在 lambda 表达式中访问外层的局部变量。

public class Java8Tester {
 
   final static String salutation = "Hello! ";
   
   public static void main(String args[]){
      GreetingService greetService1 = message -> 
      System.out.println(salutation + message);
      greetService1.sayMessage("Runoob");
   }
    
   interface GreetingService {
      void sayMessage(String message);
   }
}

        Lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)。

int num = 1;  
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;  
//报错信息:Local variable num defined in an enclosing scope must be final or effectively 
 final

        在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

String first = "";  
Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length());  //编译会出错 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值