将对象转换为Map并返回

在大型企业应用程序中,有时我们需要将数据对象与Map相互转换。 通常,这是特殊序列化的中间步骤。 如果可以使用某种标准,则最好使用该标准,但是很多时候,一些首席架构师所设想的体系结构,严格的环境或某些类似的原因使得使用JOOQ,Hibernate,Jackson,JAX或其他某种东西成为可能。像那样。 在这种情况下,就像几年前我遇到的那样,我们必须将对象转换为字符串或二进制的某种专有格式,朝该方向的第一步是将对象转换为Map

最终,转换不仅仅是简单的

Map myMap =  (Map)myObject;

因为这些对象几乎从来都不是自己的地图。 转换中真正需要的是具有一个Map ,其中每个条目都对应于“ MyObject”类中的一个字段。 条目中的关键字是字段的名称,值是可能转换为Map本身的字段的实际值。

一种解决方案是使用反射并以反射方式读取对象的字段并从中创建地图。 另一种方法是在需要转换为Map的类中创建toMap()方法,该方法只需使用字段名称将每个字段简单地添加到返回的Map中即可。 这比基于反射的解决方案要快一些,并且代码要简单得多。

几年前,当我在一个实际的应用程序中遇到这个问题时,我为每个数据对象编写原始但众多的toMap()方法感到沮丧,以至于我创建了一个简单的基于反射的工具,该工具可以针对我们想要的任何类进行操作。 它解决了问题吗? 没有。

这是一个专业的环境,在这里不仅功能很重要,而且代码质量和我的程序员的判断所得出的我的代码质量都不匹配。 他们认为基于反射的解决方案很复杂,如果它成为代码库的一部分,那么后来加入普通开发人员将无法维护它。 好吧,我不得不承认它们是正确的。 在不同的情况下,我会说开发人员必须在Java所需的水平上学习Java的反射和编程。 但是,在这种情况下,我们不是在谈论某个特定的人,而是在将来某个人加入并加入团队,可能是在我们已经离开该项目的某个时候。 假定此人是普通开发人员,这似乎很合理,因为我们对该人一无所知。 从这个意义上讲,代码质量不好,因为它太复杂了。 开发人员团队的法定人数决定,维护许多手动制作的toMap()方法比将来寻找高级和有经验的开发人员要便宜。

老实说,我有点不愿意接受他们的决定,但是即使我仅根据我在团队中的职位就可以推翻它,我还是接受了它。 即使我不同意,但我倾向于接受团队的决定,但前提是我可以接受这些决定。 如果一项决定是危险的,可怕的并且威胁着项目的未来,那么我们必须继续讨论细节,直到达成协议。

几年后,我开始创建Java :: Geci作为副项目,可以从http://github.com/verhas/javageci下载

Java :: Geci是在Java开发生命周期的测试阶段运行的代码生成工具。 Java :: Geci中的代码生成是一个“测试”。 它运行代码生成,并且如果所有生成的代码都保留下来,则测试成功。 如果代码库中的任何内容发生了更改,导致代码生成器生成的代码与以前不同,因此源代码发生了更改,则测试将失败。 如果测试失败,则必须修复该错误并运行构建,包括再次进行测试。 在这种情况下,测试将生成新的,现已固定的代码,因此您所要做的只是再次运行构建。

在开发框架时,我创建了一些简单的生成器来生成equals()hashCode() ,设置器和获取器,委托生成器,最后我无法抗拒,但创建了通用的toMap()生成器。 该生成器生成的代码将对象转换为Map ,就像我们之前讨论的一样,还有我之前未提到的fromMap() ,但显然也需要。

Java :: Geci生成器是实现Generator接口的类。 Mapper生成器可以扩展抽象类AbstractJavaGenerator 。 这使生成器可以抛出任何异常,从而简化了生成器开发人员的工作,并且它已经在查找从当前已处理的源生成的Java类。 生成器可以通过参数klass来访问实际的Class对象,同时可以通过参数source来访问源代码, source代表源代码并提供创建要插入其中的Java代码的方法。

第三个global参数类似于保存源代码注释@Geci定义的配置参数的映射。

package javax0.geci.mapper;import ...public class Mapper extends AbstractJavaGenerator {...@Overridepublic void process(Source source, Class<?> klass, CompoundParams global)throws Exception {final var gid = global.get("id");var segment = source.open(gid);generateToMap(source, klass, global);generateFromMap(source, klass, global);final var factory = global.get("factory", "new {{class}}()");final var placeHolders = Map.of("mnemonic", mnemonic(),"generatedBy", generatedAnnotation.getCanonicalName(),"class", klass.getSimpleName(),"factory", factory,"Map", "java.util.Map","HashMap", "java.util.HashMap");final var rawContent = segment.getContent();try {segment.setContent(Format.format(rawContent, placeHolders));} catch (BadSyntax badSyntax) {throw new IOException(badSyntax);}}

生成器本身仅调用这两个方法generateToMap()generateFromMap() ,这两个方法generateToMap() ,其名称暗示将toMap()fromMap()方法引入类。

两种方法都使用Segment类提供的源生成支持,还使用Jamal提供的模板。 还需要注意的是,这些字段是通过调用反射工具方法getAllFieldsSorted()来收集的,该方法返回该类具有确定顺序的所有字段,而不依赖于实际的JVM供应商或版本。

private void generateToMap(Source source, Class<?> klass, CompoundParams global) throws Exception {final var fields = GeciReflectionTools.getAllFieldsSorted(klass);final var gid = global.get("id");var segment = source.open(gid);segment.write_r(getResourceString("tomap.jam"));for (final var field : fields) {final var local = GeciReflectionTools.getParameters(field, mnemonic());final var params = new CompoundParams(local, global);final var filter = params.get("filter", DEFAULTS);if (Selector.compile(filter).match(field)) {final var name = field.getName();if (hasToMap(field.getType())) {segment.write("map.put(\"%s\", %s == null ? null : %s.toMap0(cache));", field2MapKey(name), name, name);} else {segment.write("map.put(\"%s\",%s);", field2MapKey(name), name);}}}segment.write("return map;")._l("}\n\n");}

该代码仅选择由filter表达式表示的字段。

翻译自: https://www.javacodegeeks.com/2019/06/converting-objects-map-back.html

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

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

相关文章

多串口服务器的工作方式及接线示意图介绍

串口服务器提供串口转网络功能&#xff0c;能够将RS-232/485/422串口转换成TCP/IP网络接口&#xff0c;实现RS-232/485/422串口与TCP/IP网络接口的数据双向透明传输。那么&#xff0c;多串口服务器是怎么工作&#xff0c;怎么接线的&#xff1f;接下来就由飞畅科技小编一起来为…

多路串口服务器的应用及应用范围介绍

串口服务器的应用领域很是广泛&#xff0c;主要应用在门禁系统、考勤系统、售贩系统、POS系统、楼宇自控系统、自助银行系统、电信机房监控、电力监控等。接下来就由飞畅科技的小编来为大家详细介绍下多路串口服务器的应用及应用范围&#xff0c;感兴趣的朋友就一起来看看吧&am…

javafx 调用接口_JavaFX技巧3:使用回调接口

javafx 调用接口作为UI框架开发人员&#xff0c;提供自定义控件外观和行为的方法是我工作的一部分。 在许多情况下&#xff0c;这是通过允许框架用户在控件上注册工厂来完成的。 过去&#xff0c;我会为此创建一个工厂接口&#xff0c;并在框架内提供一个或多个默认实现。 这些…

工业串口服务器如何使用

串口联网服务器让传统的RS-232/422/485设备立即联网&#xff0c;利用基于TCP/IP的串口数据流传输的实现来控制管理的设备硬件是专为串口转以太网设计连接的桥梁。那么&#xff0c;我们该如何正确使用工业串口服务器呢&#xff1f;接下来我们就跟随飞畅科技的小编一起来看看吧&a…

JMetro 5.5版发布

JMetro 5.5版刚刚发布。 进行了重大更新&#xff0c;其中添加了一些错误修复&#xff0c;样式和功能。 一个新的主题测试器示例应用程序也已添加到示例子项目中&#xff0c;该应用程序测试了几项内容&#xff0c;例如控件之间的对齐。 我将尽量使这篇文章简短&#xff0c;因为…

关于工业级RS485串口服务器的组网方式详解

工业级串口服务器提供串口转网络功能&#xff0c;是实现串口&#xff08;TTL串口或RS232/RS485/RS422&#xff09;数据与TCP/IP协议数据相互转换实现数据通过网络传输的工业互联通讯设备。通过连接多个串口设备并将串口数据流进行选择和处理&#xff0c;将串口数据转换为以太网…

什么是四路串口服务器?

四路串口RS232/RS422/RS485设备联网服务器&#xff08;以下简称&#xff1a;串口服务器&#xff09;是由杭州飞畅科技自主研发的串口设备联网产品&#xff0c;其中RS232/RS422/RS485可以任意组合使用(客户可定制&#xff09;。那么&#xff0c;什么是四路串口服务器&#xff1f…

Java中的代理设计模式

代理对象或代理对象为另一个对象提供占位符&#xff0c;以控制对该对象的访问。 代理充当原始对象的轻量级版本或简化版本。 它支持与原始对象相同的操作&#xff0c;但可以将那些请求委托给原始对象以实现它们。 代理设计模式是一种结构模式&#xff0c;其中代理类包装了实际…

光模块简介、结构介绍及分类详解

光模块(optical module)由光电子器件、功能电路和光接口等组成&#xff0c;光电子器件包括发射和接收两部分。简单的说&#xff0c;光模块的作用就是光电转换&#xff0c;发送端把电信号转换成光信号&#xff0c;通过光纤传送后&#xff0c;接收端再把光信号转换成电信号。接下…

光模块是怎么分类的?光模块的应用及作用有哪些?

光模块是进行光电和电光转换的光电子器件。光模块的发送端把电信号转换为光信号&#xff0c;接收端把光信号转换为电信号。光模块按照封装形式分类&#xff0c;常见的有SFP&#xff0c;SFP&#xff0c;SFF&#xff0c;千兆以太网路界面转换器&#xff08;GBIC&#xff09;等。那…

仿制药名言_仿制药的美丽与陌生

仿制药名言最近&#xff0c;我正在为Oracle认证专家Java SE 7程序员考试做准备&#xff0c;而我恰巧在Java泛型领域遇到了一些看起来很奇怪的构造。 但是&#xff0c;我也看到了一些巧妙而优雅的代码。 我发现这些示例值得分享&#xff0c;这不仅是因为它们可以使您的设计选择更…

如何区分光猫、路由器和交换机?

如今&#xff0c;网络已经进入了千家万户&#xff0c;上网已成为了我们生活中必不可少的事情。通常&#xff0c;在家里最常见的网络设备有&#xff1a;光猫&#xff08;光调制解调器&#xff09;、路由器、交换机&#xff0c;但很多小白用户并不能轻易区分它们。当遇上网络故障…

Java 12:开关表达式

在Java 12中&#xff0c;对switch语句进行了增强&#xff0c;以便可以将其用作表达式。 现在也可以在一种情况下打开多个常量&#xff0c;从而使代码更简洁易读。 这些增强是预览语言功能 &#xff0c;这意味着必须使用--enable-preview标志在Java编译器和运行时中显式启用它们…

什么是网络延长器?

网络延长器就是能够把网络传输距离有效延长的设备&#xff0c;网络延长器能够突破传统以太网传输距离100米以内的限制&#xff0c;可以通过双绞线将100M网络传输500米&#xff0c;10M网络传输1500米甚至更长。它将网络的传输距离的极限从铜线的100米扩展到千米以上&#xff0c;…

什么是延长器?延长器常见类型介绍

延长器是用来延长信号的器件&#xff0c;通常用于长距离直连线材无法满足传输要求的情况&#xff0c;一般是为了确保信号长距离无衰减的传输而设计&#xff0c;因此多是有源的。那么&#xff0c;什么是延长器&#xff1f;延长器的常见类型有哪些呢&#xff1f;接下来我们就一起…

solr 模糊匹配_Solr中的前缀和后缀匹配

solr 模糊匹配搜索引擎都是关于查找字符串的。 用户输入一个查询词&#xff0c;然后从反向索引中检索它。 有时&#xff0c;用户正在寻找的值只是索引中值的子字符串&#xff0c;并且用户可能也对这些匹配感兴趣。 对于德语这样的包含复合词&#xff08;如Semmelkndel&#xff…

视频编解码器常见问题介绍

视频编解码器&#xff0c;是指一个能够对数字视频进行压缩或者解压缩的程序或者设备。通常这种压缩属于有损数据压缩。历史上&#xff0c;视频信号是以模拟形式存储在磁带上的。那么&#xff0c;我们在使用视频编解码器的过程中遇到的一些常见问题有哪些呢&#xff1f;接下来我…

Java中的双重检查锁定

在本文中&#xff0c;我们将介绍在RxJava中创建Singleton对象的一些技术。 最重要的是&#xff0c;我们将学习Java中的双重检查锁定 。 Java中的Singleton模式是一种创新模式。 随着时间的流逝&#xff0c;人们开始关注Singleton模式的使用和实现。 这是由于单例的实现和使用方…

视频干扰的原因及解决方法

我们在视频监控和视频传输会议中常常会遇到视频信号被干扰的困扰&#xff0c;由于视频干扰产生画面抖动、显示模糊等显示问题&#xff0c;严重影响使用效果。那么这些干扰信号时如何产生的&#xff0c;又该如何解决呢&#xff1f;接下来我们就跟随飞畅科技的小编一起来详细了解…

网络监控系统安装的4种方式,安防必备

现如今&#xff0c;随着人们安防意识的提高&#xff0c;监控从业人员也越来越多。对于刚刚加入这个行业的新人来讲&#xff0c;可能首先要从最基层的监控设备安装做起。只有在实践中不断积累经验技术&#xff0c;才有可能独当一面、快速成长。作为一名新手&#xff0c;网络监控…