转载请注明出处: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);
}
@Override
public String toString() {
return entry.toString();
};
/**
* 获取Object类型的值
* @param key
* @return
*/
public Object getObject(String key){
return getValue(Object.class,key);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((entry == null) ? 0 : entry.hashCode());
return result;
}
@Override
public 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 Type
private String key; // DTO Attribute Name
private T value; // DTO Attribute Value
private 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;
}
@Override
public 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;
}
@Override
public 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;
}
@Override
public 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));
}
}