Lambda 的延迟执行

Lambda 的延迟执行

使用 Lambda 表达式的主要原因是:将代码的执行延迟到一个合适的时间点,即调用的时候。

所有的 Lambda 表达式都是延迟执行的。

因为匿名内部类的方法都是要等到调用的时候才会执行。

延迟执行的基本案例:

案例需求:1) 创建一个 Person 接口,有一个 sayHi()的无参无返回值的方法。

2) 在 main 函数中直接实例化 Person 为 p1 对象,并且实现 sayHi()方法,

此时方法并没有执行,因为方法不调用不执行。

3) 在后面输出一句话:主函数执行4) 再调用 sayHi()方法,才发现 sayHi()方法的输出。5) 同理使用 Lambda 也是一样的效果。

案例代码:

public class DemoLazy {
 public static void main(String[] args) {
 //这里实例化对象,并没有执行 sayHi 中的方法
 Person p1 = new Person() {
 @Override
 public void sayHi() {
 System.out.println("来至内部类的问候");
 }
 };
 System.out.println("主函数运行");
 //这里才输出
 p1.sayHi();
 //同理,这里是没有运行方法体的
 Person p2 = ()-> System.out.println("来至 Lambda 的问候");
 //调用的时候才运行
 p2.sayHi();
 }
}
interface Person {
 void sayHi();
}
有些场景的代码执行后,结果不一定会被使用,从而造成性能浪费。

 Lambda 表达式是延迟执行的,这正好可以作为解决方案,减少无用代码的执行,提升性能。

案例需求:1) 有一个静态方法: void log(int level, String message),当它为日志级别为 1 级的时候,打印出日志的信息。2) 在 main 函数中创建一个时间格式化的类,格式是:yyyy-MM-dd HH:mm:ss.SSS3) 在 main 函数中调用 2 次 log()方法,1 级调用 1 次,2 级调用 1 次。4) 第 1 次日志信息内容是:"Rose: " + sdf.format(new Date()) + " 进行了转账操作"5) 第 2 次日志信息内容是:"Jack: " + sdf.format(new Date()) + " 进行了取钱操作"

public class DemoLazy {

 public static void main(String[] args) {

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

 log(1, "Rose: " + sdf.format(new Date()) + " 进行了转账操作");

 log(2, "Jack: " + sdf.format(new Date()) + " 进行了取钱操作");

 }

 /**

- 记录日志
- @param level 日志级别
- @param message 日志信息
  */
   public static void log(int level, String message) {
   if (level == 1) { // 用户日志
   System.out.println(message);
   }
   }
  }

案例分析:

1) 在 log 方法的内部设置断点,证明两次都会对字符串进行计算。2) 存在问题:字符串拼接完成之后,在调用 log 方法后可能不会被使用,

​ 那么此时之前的拼接工作就白做了,这样就会浪费性能。

Lambda 的更优写法案例分析1) 创建一个接口 BuilderMessage,接口中有一个抽象方法 String buildeMessage(),返回字符串。2) 创建类,创建静态方法用于输出日志信息:static void log(int level, BuilderMessage bulider)在方法内部判断如果是 1 级信息,打印日志信息,并调用接口中的 buildeMessage()方法拼接字符串。3) 在 main 函数中创建日期格式化类,调用 2 次 log()方法:1 级调用 1 次,2 级调用 1 次。log 方法的第 2 个参数使用 Lambda 表达式,方法体中使用 return 返回拼接的字符串。4) 第 1 次信息内容是:"Rose: " + sdf.format(new Date()) + " 进行了转账操作"5) 第 2 次信息内容是:"Jack: " + sdf.format(new Date()) + " 进行了取钱操作"

创建一个拼接字符串的接口,函数式接口

interface BuilderMessage {
 String buildeMessage();
}

public class DemoLazy {
记录日志
- @param level 日志级别
- @param bulider 日志信息
  */
   public static void log(int level, BuilderMessage bulider) {
   if (level == 1) { // 用户日志
   System.out.println(bulider.buildeMessage());
   }
   }
   public static void main(String[] args) {
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
   log(1, () -> {return "Rose: " + sdf.format(new Date()) + " 进行了转账操作";});
   log(2, () -> {return "Jack: " + sdf.format(new Date()) + " 进行了取钱操作";});
   }
  }

证明 Lambda 的延迟执行

案例分析:

在 Lambda 表达式方法体中返回字符串之前,

先输出当前的级别,发现只输出了级别 1,级别 2 并没有输出。

即当级别为 2 时,没有对字符串进行拼接操作了,这样就避免了拼接字符串带来的额外开销。

  /**
   创建一个拼接字符串的接口,函数式接口
  */
  interface BuilderMessage {
   String buildeMessage();
  }
  public class DemoLazy {
   /**
- 记录日志
- @param level 日志级别
- @param bulider 日志信息
  */
   public static void log(int level, BuilderMessage bulider) {
   if (level == 1) { // 用户日志
   System.out.println(bulider.buildeMessage());
   }
   }
   public static void main(String[] args) {
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
   log(1, () -> {
   System.out.println("级别 1");
   return "Rose: " + sdf.format(new Date()) + " 进行了转账操作";
   });
   log(2, () -> {
   System.out.println("级别 2");
   return "Jack: " + sdf.format(new Date()) + " 进行了取钱操作";
   });
   }
  }

延迟执行小结:

只有在需要的时候才能运行代码,这是使用 lambda 表达式的一种情况。void log(int level, BuilderMessage bulider) 这段代码实际的运行效果分如下步骤:1) 通过 BuilderMessage 接口接受 lambda 表达式。2) 检查它是否应该被调用,即 level 是否等于 1。3) 在需要的时候调用它,bulider.buildeMessage()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值