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
java中延迟