Java中的延迟分配

程序员本来就是懒惰的,而similis simili gaudet就像程序是懒惰的一样。 您听说过延迟加载吗? 还是懒惰的单身人士? (不过,我个人更喜欢单一麦芽版本。)如果使用Scala或Kotlin(这也是一种JVM语言)进行编程,则您甚至可以以惰性方式评估表达式。

如果您在Scala中编程,则可以编写

 lazy val z = "Hello" 

并且仅在首次访问z时才对表达式求z 。 如果您使用Kotlin编程,则可以编写如下内容

 val z: String by lazy { "Hello" } 

并且仅在首次访问z时才对表达式求z

Java本身不支持这种惰性评估,但是作为一种功能强大的语言,Java提供了可用于获得相同结果的语言元素。 当Scala和Kotlin给您鱼时,Java教您捕获自己的鱼。 (让我们在这个想法中发挥作用。)

当您在Scala和/或Kotlin中对以上行进行编码时,在后台真正发生的事情是不对表达式进行求值,并且变量将不包含表达式的结果。 相反,这些语言会创建一些虚拟的“ lambda”表达式,这是一个“供应商”,以后将用于计算该表达式的值。

我们可以用Java自己完成。 我们可以使用一个简单的类Lazy提供以下功能:

 public class Lazy implements Supplier {  final private Supplier supplier;  supplied = private boolean supplied = false ;  private T value;  private Lazy(Supplier supplier) {  this .supplier = supplier;  }  public static Lazy let(Supplier supplier) {  return new Lazy(supplier);  }  @Override  public T get() {  if (supplied) {  return value;  }  supplied = true ;  return value = supplier.get();  }  } 

该类具有可用于定义供应商的public static方法let() ,并且在首次调用方法get()会调用此供应商。 使用此类,您可以将以上示例编写为

 var z = Lazy.let( () -> "Hello" ); 

顺便说一句,它似乎比Kotlin版本更简单。 您可以使用库中的类:

 com.javax0  lazylet  1.0.0 

然后您无需将代码复制到您的项目中。 这是一个微型库,仅包含此类和一个内部类,该内部类使Lazy可以在多线程环境中使用。

用法很简单,如单元测试所示:

 private static class TestSupport {  int count = 0 ;  boolean callMe() {  count++;  return true ;  }  }  ...  final var ts = new TestSupport();  var z = Lazy.let(ts::callMe);  if ( false && z.get()) {  Assertions.fail();  }  Assertions.assertEquals( 0 , ts.count);  z.get();  Assertions.assertEquals( 1 , ts.count);  z.get();  Assertions.assertEquals( 1 , ts.count); 

要获取多线程安全版本,可以使用以下代码:

 final var ts = new TestSupport();  var z = Lazy.sync(ts::callMe);  if ( false && z.get()) {  Assertions.fail();  }  Assertions.assertEquals( 0 , ts.count);  z.get();  Assertions.assertEquals( 1 , ts.count);  z.get();  Assertions.assertEquals( 1 , ts.count); 

并获得可以由多个线程使用的Lazy供应商,但仍可以保证作为参数传递的供应商仅传递一次。

给你一条鱼或教你钓鱼

我说要在便签上写上别针:“虽然Scala和Kotlin给您鱼,但是Java教您捕捉自己的鱼。” 这就是我的意思。

许多程序员在不了解程序如何执行的情况下编写程序。 他们使用Java编程并且编写了不错的代码,但是他们不知道底层技术是如何工作的。 他们对类加载器,垃圾回收一无所知。 或者他们知道,但是他们对JIT编译器生成的机器代码一无所知。 或者他们甚至这样做,但他们对处理器缓存,不同的内存类型,硬件体系结构一无所知。 或者他们知道但不了解微电子学和光刻技术,以及集成电路的布局,电子在半导体内部的移动方式,量子力学如何确定计算机的不确定内部工作方式。

我并不是说您必须是物理学家,并且要了解量子力学的复杂细节才能成为优秀的程序员。 但是,我建议您了解日常工作工具下面的几层内容。 如果您使用Kotlin或Scala,则绝对可以使用它们提供的惰性结构。 在这种特定情况下,它们使编程抽象比Java提供的编程抽象高一个级别。 但是,至关重要的是要知道实现的外观。 如果您知道如何钓鱼,则可以购买包装鱼,因为这样您就可以分辨出什么时候才是好鱼。 如果您不知道如何钓鱼,您将依靠那些给您钓鱼的人的怜悯。

翻译自: https://www.javacodegeeks.com/2019/05/lazy-assignment-java.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值