Java 8函数式编程:延迟实例化

单例通常会延迟实例化自己,有时,如果对象足够重,则可以延迟实例化类字段。

通常,在走惰性路线时,getter方法(或accessor )必须具有一段代码,该代码块在返回对象之前检查对象是否已实例化(如果不是,则需要实例化)。 一旦实例化了对象,该检查就没有意义。 它只会减慢已经(通常)使用同步或锁定进行阻塞的方法的速度。 让我们看一下删除该代码的方法,对吧?

免责声明

我没有想到这个。 我是从Venkat Subramaniam的Java函数编程中获得的。 我强烈推荐这本书和作者。 Venkat所阅读的所有内容都做得很好,而且易于学习。

它是如何工作的?

基本思想是:

  1. 将延迟实例化的字段替换为所需类型的供应商。
  2. 供应商实例化该对象(但尚未返回)
  3. 然后将字段设置为仅返回实例化对象的新Supplier
  4. 返回实例

因此,让我们看看实际情况。 我们将有一个名为Holder的类,该类希望延迟实例化Heavy类型的对象。 此代码直接从Venkat的书中编译而成:

public class Holder
{private Supplier heavy = () -> createAndCacheHeavy();public Heavy getHeavy(){return heavy.get();}private synchronized Heavy createAndCacheHeavy(){class HeavyFactory implements Supplier{private final Heavy heavyInstance = new Heavy();public Heavy get(){return heavyInstance;}}if(!HeavyFactory.class.isInstance(heavy)){heavy = new HeavyFactory();}return heavy.get();}
}

现在,此代码可以正常工作,但是我发现createAndCacheHeavy的实现不必要地令人困惑。 第一次看到此代码时,我花了很长时间才弄清楚它在做什么。

因此,让我们对其进行一些修改,对吧? 我们将使它看起来像是按照我之前列出的步骤进行操作。

private Heavy createAndCacheHeavy()
{Heavy instance = new Heavy();heavy = () -> instance;return instance;
}

那不是更好吗? 我认为,这比以前更简单,更干净。 而且仍然有效! 好吧,这里有一个小警告:为了使代码具有线程安全性,您需要同步getInstance()方法而不是createAndCacheHeavy方法。 与Venkat的代码相比,这种更改会使代码的速度稍慢一些,因为一旦HeavyFactory就绪,他的代码就不会使用同步。 但是它仍然比每次都需要同步和有条件检查的旧方法要快。

因此,这是一些有用的代码,但是您是否想在每次懒惰地实例化某些东西时都键入该代码? 我不这么认为。 因此,让我们创建一个可重用的类,使我们的生活更加轻松。

但是首先,只是为了向您展示它变得更容易使用,让我向您展示它的使用情况。

Supplier<Heavy> heavy = LazilyInstantiate.using(() -> new Heavy());

而已! 让我们更仔细地看一下它,并深入研究它,然后再进行研究。

该行的声明位与以前相同; 一家名为Heavy的重型供应商。 但是随后我们调用了LazilyInstantiate的静态方法,该方法原来是返回工厂实现Supplier的LazilyInstantiate对象的静态工厂方法。 传递给该方法的参数是在那里的“重型供应商”,因此用户可以为实例化器提供正确的代码以实例化对象。

那么,您是否对它的工作方式感到好奇? 好了,这是LazilyInstantiate的代码:

public class LazilyInstantiate implements Supplier
{public static  LazilyInstantiate using(Supplier supplier){return new LazilyInstantiate<>(supplier);}public synchronized T get(){return current.get();}private LazilyInstantiate(Supplier supplier){this.supplier = supplier;this.current = () -> swapper();}private final Supplier supplier;private Supplier current;private T swapper(){T obj = supplier.get();current = () -> obj;return obj;}
}

您可能会发现我的方法的顺序与通常的方法有所不同。 我更喜欢先拥有公共资源,然后拥有私有和受保护包,然后拥有私有资源。 在这些块中,我执行静态字段,然后构造函数,然后是静态方法,然后是普通字段,然后是普通方法。 通常,对于用户阅读我的代码而言,这似乎按照最重要的顺序将其排序为最不重要。

您可以随意将代码复制到任何地方,也可以在github上查看我的function-java库 ,该库具有此类的完整文档版本(func.java.lazy.LazilyInstantiate)和许多其他有用的函数类。

翻译自: https://www.javacodegeeks.com/2015/01/java-8-functional-programming-lazy-instantiation.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ant-design官网打不开 , 需要用镜像地址打开

如果网络不好的时候ant-design 的官网很难打开的 &#xff0c;用下面的镜像地址就可以打开啦 ant-design 官网镜像地址: http://ant-design.gitee.io/index-cn ant-design-pro镜像地址&#xff1a; http://ant-design-pro.gitee.io/index-cn antd-mobile镜像地址&#xff1a; …

全排列函数、组合函数

1 1、求一个全排列函数&#xff1a;如p([1,2,3])输出&#xff1a; [123],[132],[213],[231],[321],[312]. 2、求一个组合函数如p([1,2,3])输出&#xff1a; [1],[2],[3],[1,2],[2,3],[1,3],[1,2,3] 这两问可以用伪代码。 void swap(int *a, int *b) //交换函数 {int tmp;tmp *a…

Java中的XSL转换:一种简单的方法

XSL转换 &#xff08;XSLT&#xff09;是将一个XML文档转换为另一个XML文档的强大机制。 但是&#xff0c;在Java中&#xff0c;XML操作相当冗长和复杂。 即使是简单的XSL转换&#xff0c;也必须编写几十行代码—如果需要适当的异常处理和日志记录&#xff0c;甚至可能还要写更…

修改html页面的title,可以自定义

方式一&#xff1a; document.getElementsByTagName(“title”)[0].innerText ‘需要设置的值’; document.title方式 经过测试&#xff0c;还可通过document.title 设置title的值。方式二 console.log(document.title); # 可以获取title的值。 document.title ‘需要设置的值…

.Net环境下的缓存技术介绍 (转)

摘要: 介绍缓存的基本概念和常用的缓存技术&#xff0c;给出了各种技术的实现机制的简单介绍和适用范围说明&#xff0c;以及设计缓存方案应该考虑的问题&#xff08;共17页&#xff09; 1 概念 1.1 缓存能解决的问题 性能——将相应数据存储起来以避免数据的重复创…

antd Datepicker组件报错 ——date.clone is not a function或者date1.isAfter is not a function

问题描述&#xff1a; antd Datepicker组件报错 ——date.clone is not a function或者date1.isAfter is not a function 原因分析&#xff1a; 在From中渲染默认值&#xff0c;一般数据请求拿到返回值存在异步&#xff0c;会晚于渲染&#xff0c;因此日期转换不能放在DatePi…

集成CDI和WebSockets

考虑尝试一个简单的Java EE 7原型应用程序&#xff0c;该应用程序涉及JAX-RS&#xff08;REST&#xff09;&#xff0c;WebSockets和CDI。 注意 &#xff1a;不想让它成为破坏者-但这篇文章主要讨论了我在尝试使用Web套接字和使用CDI作为“胶水”的REST&#xff08;在Java EE应…

【记】jQuery中的选择器:visible对visibility:hidden的处理

首先先介绍visibility这个CSS属性。 visibility用于表示该元素是否显示&#xff0c;其取值有&#xff1a; visible&#xff1a;设置对象可视。  hidden&#xff1a;设置对象隐藏。  collapse&#xff1a;主要用来隐藏表格的行或列&#xff0c;隐藏的行或列能够被其他内容是…

React - antd4 中在form中为Switch赋值无效

项目场景&#xff1a; React - antd4; From表单 问题描述&#xff1a; Switch赋初始值无效 # 解决方案&#xff1a; let newCheck {};if (propsForm.type switch) {newCheck {...newCheck,valuePropName: "checked"}}<Form.Itemkey{propsForm.id}name{propsF…

在实践中重试HTTP标头

Retry-After是鲜为人知的HTTP响应标头。 让我引用RFC 2616&#xff08;HTTP 1.1规范&#xff09;的相关部分&#xff1a; 14.37重试后 Retry-After响应标头字段可与503 &#xff08; 服务不可用 &#xff09;响应一起使用&#xff0c;以指示请求该客户端的服务预计无法使用多…

Java中连接字符串的最佳方法

最近有人问我这个问题–在Java中使用运算符连接字符串是否对性能不利&#xff1f; 这让我开始思考Java中连接字符串的不同方法&#xff0c;以及它们如何相互对抗。 这些是我要研究的方法&#xff1a; 使用运算符 使用StringBuilder 使用StringBuffer 使用String.concat() …

时间转换以及公式

moment(item.updatedAt).fromNow() ;//距离今天多久了moment&#xff08;&#xff09;获得今天、明天和昨天的日期 let today moment(new Date());let tomorrow moment(new Date()).add(1,days);let yesterday moment(new Date()).add(-1, days);后续遇到继续补充

只不过是R.java文件的特性-----出错信息:R.java was modified manually! Reverting to generated version!...

出错信息:R.java was modified manually! Reverting to generated version! 出错原因&#xff1a;今天在res下建立了一个drawable的文件夹存放图片资源----图片名为1.jpg 后来R.java文件就报错了&#xff1a;R.java was modified manually! Reverting to generated version! 看…

十大最常见的Java性能问题

Java性能是所有Java应用程序开发人员都关心的问题&#xff0c;因为快速使应用程序与使其正常运行同等重要。 史蒂文海恩斯&#xff08;Steven Haines&#xff09;使用他在Java性能问题上的个人经验得出的结论是&#xff0c; 大多数问题都有共同的根本原因 。 因此&#xff0c;作…

antd form 初始化时间

initialValue: moment(record.showTime, YYYY-MM-DD HH:mm:ss)

uni-app 组件中的canvas转化为图片报错:errMsg:“canvasToTempFilePath:fail canvas is empty”

项目场景&#xff1a; uni-app,开发微信小程序 使用&#xff1a; wx.canvasToTempFilePath({canvasId: line,success: function(res) {console.log(canvasToImg, res);this.radarImg res.tempFilePath;},fail: function(res) {console.log(res);}});问题描述&#xff1a; ec…

正确获取Java事件通知

实现观察者模式以提供Java事件通知似乎是一件容易的事。 但是&#xff0c;容易陷入一些陷阱。 这是我在各种场合不慎造成的常见错误的解释…… Java事件通知 让我们从一个简单的bean StateHolder开始&#xff0c;它封装了带有适当访问器的私有int字段state &#xff1a; publ…

使用fn函数控制页面显示内容

在使用&#xff25;&#xff2c;的时候&#xff0c;不可避免的遇到&#xff0c;截取字符串&#xff0c;判断字符串长度等情况。这里给出简单的通过&#xff46;&#xff4e;函数操作字符串的deamon。 1、页面引入标签 <% taglib prefix"c" uri"http://java.s…

uni-app微信获取手机号,第一次解密总是失败

项目场景&#xff1a; uni-app; 获取code&#xff0c;后台解密手机号 问题描述&#xff1a; 每次第一次登陆&#xff0c;后台都会解密失败 原因分析&#xff1a; code获取错误&#xff1b;导致后台的解密key与code不对应 解决方案&#xff1a; 小程序获取手机号之前&#xf…