转载请注明出处:https://blog.csdn.net/jevonsCSDN/article/details/87739164 【Jevons’Blog】

本文旨在简化需要多元化DTO的轻量场景,该动态DTO内部结构采用单链形式存储数据,基本满足大部分需要临时创建DTO、临时校验、基于属性的映射绑定等场景,不必为了一些对象去创建一堆java文件或是一堆散乱的映射逻辑,支持同一个Key下存在多个不同类型的value(泛型除外),极大提高了代码简洁性和数据聚集性。


import java.util.ArrayList;
import java.util.List;/*** 动态DTO对象* <br>******************************** <br>主要用于需要创建临时Dto的轻量场景(非线程安全类)* <br>******************************** @author Zhang HaoWen* @date 2018年4月18日*/
public class DynamicDto{private  Entry<?> entry =null;public DynamicDto() {// TODO Auto-generated constructor stub}/*** 设置动态Dto对象属性* @param type* @param instance* @return*/public  <T> DynamicDto set(String key ,T value){if(value==null){throw new NullPointerException("The value must not to be null!");}@SuppressWarnings("unchecked")Class<T> type = (Class<T>) value.getClass();Entry<T> entryExist = getEntry(type, key);if(entryExist!=null){entryExist.setValue(value);}else{Entry<T> newEntry = new Entry<T>(type, key, value, entry);this.entry = newEntry;}return this;}/*** 根据type和key来删除动态Dto的一个属性* @param <T>* @param type* @param key* @return */public <T> boolean remove(Class<T> type,String key){Entry<?> newEntry  = entry;Entry<?> upperEntry = null;while (newEntry!=null) {if(type == newEntry.getType()){if((key==null&&newEntry.getKey()==null)||key.equals(newEntry.getKey())){if(upperEntry==null){//如果upperEntry为空,说明为最后加入单链的元素,直接用下一个元素顶替this.entry=newEntry.next;}else{upperEntry.next=newEntry.next;}return true;}else{upperEntry=newEntry;newEntry=newEntry.next;}}else{upperEntry=newEntry;newEntry=newEntry.next;}}return false;}/*** 移除动态Dto所有属性*/public void removeAll(){this.entry=null;}/*** 获取Entry* @param type* @param key* @return*/@SuppressWarnings("unchecked")private <T> Entry<T> getEntry(Class<T> type,String key){Entry<?> newEntry = entry;while (newEntry!=null) {if(type == newEntry.getType()){if((key==null&&newEntry.getKey()==null)||key.equals(newEntry.getKey())){return (Entry<T>) newEntry;}else{newEntry=newEntry.next;}}else{newEntry=newEntry.next;}}return null;}/*** 获取Dto对象属性* @param type* @param key* @return*/public <T> T getValue(Class<T> type,String key){Entry<?> newEntry = entry;while (newEntry!=null) {if(type == newEntry.getType()){if(key==null&&newEntry.getKey()==null){return type.cast(newEntry.getValue());}else if(key.equals(newEntry.getKey())){return type.cast(newEntry.getValue());}else{newEntry=newEntry.next;}}else{newEntry=newEntry.next;}}return null;}/*** 设置String类型的属性值* @param <T>* @param key* @return*/public void setString(String key,String value){set(key,value);}/*** 根据key来拼接String类型的值* @param key* @param value* @return*/public String append(String key,String value){String oldValue = getString(key);if(oldValue==null){setString(key, value);}else{StringBuilder sb = new StringBuilder(oldValue);value = sb.append(value).toString();setString(key, value);}return value;}/*** 将srcKey的属性值拼接到targetKey的属性值后* @param targetKey* @param srcKey* @return*/public String appendTo(String targetKey,String srcKey){return append(targetKey,getString(srcKey));}/*** 将srcKey的属性值依次拼接到targetKey的属性值后* @param targetKey* @param srcKey* @return*/public String appendToUnlimit(String targetKey,String... srcKey){StringBuilder sb = new StringBuilder();for(String s :srcKey){sb.append(getString(s));}return append(targetKey,sb.toString());}/*** 获取String类型的值* @param key* @return*/public String getString(String key){return getValue(String.class,key);}/*** 获取int类型的值* @param key* @return*/public Integer getInt(String key){return getValue(Integer.class,key);}/*** 获取Double类型的值* @param key* @return*/public Double getDouble(String key){return getValue(Double.class,key);}/*** 获取Float类型的值* @param key* @return*/public Float getFloat(String key){return getValue(Float.class,key);}/*** 获取Boolean类型的值* @param key* @return*/public Boolean getBoolean(String key){return getValue(Boolean.class,key);}@Overridepublic String toString() {return entry.toString();};/*** 获取Object类型的值* @param key* @return*/public Object getObject(String key){return getValue(Object.class,key);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((entry == null) ? 0 : entry.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;DynamicDto other = (DynamicDto) obj;if (entry == null) {if (other.entry != null)return false;} else if (!entry.equals(other.entry))return false;return true;}/*** 内部类,用于存储DTO属性数据*/private class Entry<T>{private Class<T> type;   // DTO Attribute Class Typeprivate String key;      // DTO Attribute Nameprivate T value;       // DTO Attribute Valueprivate Entry<?> next;  // Link To Next Attribute  public Entry(Class<T> type,String key,T value,Entry<?> n) {this.type = type;this.key    = key;this.value   = value;this.next  = n;}public Class<T> getType() {return type;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((key == null) ? 0 : key.hashCode());result = prime * result + ((next == null) ? 0 : next.hashCode());result = prime * result + ((type == null) ? 0 : type.hashCode());result = prime * result + ((value == null) ? 0 : value.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Entry other = (Entry) obj;if (key == null) {if (other.key != null)return false;} else if (!key.equals(other.key))return false;if (next == null) {if (other.next != null)return false;} else if (!next.equals(other.next))return false;if (type == null) {if (other.type != null)return false;} else if (!type.equals(other.type))return false;if (value == null) {if (other.value != null)return false;} else if (!value.equals(other.value))return false;return true;}public String getKey() {return key;}public T getValue() {return value;}public void setValue(T value) {this.value = value;}@Overridepublic String toString() {return "Entry [type=" + type + ", key=" + key + ", value=" + value+ ", next=" + next + "]";}}public static void main(String[] args) {List<String> bList = new ArrayList<>();bList.add("s");List<String> bList2 = new ArrayList<>();bList2.add("s");DynamicDto dto = new DynamicDto();dto.set("list", bList);DynamicDto dto2 = new DynamicDto();dto2.set("list", bList2);System.out.println(dto.equals(dto2));}
}

DynamicDto链式实现动态数据传输对象相关推荐

  1. Lombok链式调用,子类对象set父类属性,返回父类对象

    前言 lombok相信大家都用过,没用过肯定也不会点进来,一直用着都很舒服.今但是天在码代码时,碰到了一个问题,卡了半天.问题是这样的:Lombok链式调用父类中的set属性时,返回的居然是一个父类对 ...

  2. Java8链式调用_java链式调用(转载http://www.cnblogs.com/quiet-snowy-day/p/6091233.html)

    记录最近在项目设计中遇到的一个小问题. 前提:有这样两个POJO类,它们都可以通过链式调用的方式来设置其属性值,其中一个类继承了另一个类. 问题:通过链式调用,子类对象访问父类方法后,如何使返回对象仍 ...

  3. 【Java 网络编程】NIO Buffer 简介 ( 概念 | 数据传输 | 标记 | 位置 | 限制 | 容量 | 标记 | 重置 | 清除 | 翻转 | 重绕 | 链式操作 )

    文章目录 I. Buffer 简介 II. Buffer 属性 III. Buffer 数据读写 IV. Buffer 标记 mark() 和重置 reset() V. Buffer 清除 翻转 重绕 ...

  4. javascript --- 对象的方式体验链式调用

    将功能相近的方法写入同一个对象中,是一个很好的编程习惯,便于后期的维护和前期的开发. foo1 var fooObj = {foo1: function() {console.log('foo1'); ...

  5. c/c++教程 - 2.4.3 this指针作用,链式编程思想,空指针访问成员函数,const修饰成员函数,常函数,常对象

    目录 4.3 C++对象模型和this指针 4.3.1 成员变量和成员函数分开存储 4.3.2 this指针概念(非常重要) 4.3.3 空指针访问成员函数 4.3.4 const修饰成员函数 相关教 ...

  6. 数据结构Java实现05----栈:顺序栈和链式堆栈

    一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  7. 大话PHP设计模式:类自动载入、PSR-0规范、链式操作、11种面向对象设计模式实现和使用、OOP的基本原则和自动加载配置...

    一.类自动载入 SPL函数 (standard php librarys) 类自动载入,尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_registe ...

  8. 链表list(链式存储结构实现)_数据结构知否知否系列之 — 线性表的顺序与链式存储篇(8000 多字长文)...

    从不浪费时间的人,没有工夫抱怨时间不够. -- 杰弗逊 线性表是由 n 个数据元素组成的有限序列,也是最基本.最简单.最常用的一种数据结构. 作者简介:五月君,Nodejs Developer,热爱技 ...

  9. 请求的链式处理——职责链模式

    本文转载自 :http://blog.csdn.net/lovelion/article/details/7420891 "一对二","过","过&q ...

最新文章

  1. 潘石屹首次Python考试成绩 99 分,失分点:画完图后忘了隐藏画笔的箭头
  2. utf编码在线转换工具
  3. createDocumentFragment 详解
  4. javascript --- 利用Sortable实现一个可视化公式编辑器
  5. Android view变形,Android SurfaceView预览变形完美解决方法
  6. 一种开发AJAX的方法,ajax.dll
  7. 一些SAP Partners能够通过二次开发实现打通C/4HANA和S/4HANA的方法介绍
  8. 社会达尔文主义 盛行时间_新达尔文主义的心理理论
  9. 机器学习和深度学习资料列表
  10. 平面关系:平行,垂直,夹角判定
  11. 为什么使用MATLAB的imnoise函数添加高斯噪声时要将方差除以255^2
  12. 2018年大学生设计竞赛浙江赛区C题-无线充电电动小车-试题分析
  13. java方法的重写和重载_Java方法重载和重写原理区别解析
  14. Oracle GoldenGate for Oracle 11g(Solaris 10 x86-64) to Oracle 10g(CentOS 4.8) configuration
  15. linux把ftp挂载成盘符,使用curlftpfs将ftp空间挂载到本地
  16. 抗衡微软,三款国产软件接力金山WPS,身体力行,不愧是国产之光
  17. dat图片 电脑端微信_写了一个电脑版微信的dat图片转换器
  18. Java之手写实现ORM框架
  19. 02-nation.sql
  20. 工作流之通用数据表设计

热门文章

  1. php在线打包(hacklog修改版),wordpress配置记录
  2. 「炼丹」AutoDL炼丹日记
  3. 推流yasea遇到问题,即调转摄像头算法
  4. 使用VMD中的Tachyon渲染出透明逼真的水盒子效果
  5. 零基础从零开始写VO视觉里程计
  6. 阿里云短信认证实现过程
  7. powershell中替换文件内容的方法
  8. python2exe_Python 使用Py2exe进行bin化
  9. 服务器和普通电脑有什么区别?
  10. Excel汉字转换得到其拼音函数