|
@@ -1,22 +1,136 @@
|
|
package com.diagbot.util;
|
|
package com.diagbot.util;
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.apache.commons.lang3.Validate;
|
|
|
|
+import org.apache.commons.lang3.reflect.FieldUtils;
|
|
|
|
|
|
|
|
+import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.Method;
|
|
|
|
+import java.lang.reflect.Modifier;
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
+import java.util.Collection;
|
|
|
|
+import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
|
+import java.util.Iterator;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.LinkedHashMap;
|
|
|
|
+import java.util.LinkedHashSet;
|
|
|
|
+import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @Description: 实体对象工具类
|
|
* @Description: 实体对象工具类
|
|
* @author: gaodm
|
|
* @author: gaodm
|
|
- * @time: 2018/2/11 10:09
|
|
|
|
|
|
+ * @time: 2018/9/13 20:12
|
|
*/
|
|
*/
|
|
@Slf4j
|
|
@Slf4j
|
|
public class EntityUtil {
|
|
public class EntityUtil {
|
|
|
|
|
|
|
|
+ private static final String DATE_CLASS_NAME = Date.class.getName();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将list中元素的某一成员组装成list返回。注意:会去重!
|
|
|
|
+ * @param list 元素列表
|
|
|
|
+ * @param fieldName 成员变量的field
|
|
|
|
+ * @param <T> 元素类型
|
|
|
|
+ * @return 返回该字段组成的list
|
|
|
|
+ */
|
|
|
|
+ public static <T> List makeListByFieldName(List<T> list, String fieldName) {
|
|
|
|
+ List returnList = new LinkedList();
|
|
|
|
+ if (list.isEmpty()) {
|
|
|
|
+ return returnList;
|
|
|
|
+ }
|
|
|
|
+ Object firstObj = list.get(0);
|
|
|
|
+ Field field = FieldUtils.getField(firstObj.getClass(), fieldName, true);
|
|
|
|
+ if (field == null) {
|
|
|
|
+ throw new RuntimeException(firstObj.getClass().getName() + "不存在" + fieldName);
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ for (T o : list) {
|
|
|
|
+ if(!returnList.contains(field.get(o))) {
|
|
|
|
+ returnList.add(field.get(o));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
|
+ //懒得在外面try catch, 直接ignore
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ }
|
|
|
|
+ return returnList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将Collection中元素的某一成员组装成Set返回
|
|
|
|
+ * @param collection 元素列表
|
|
|
|
+ * @param fieldName 成员变量的field
|
|
|
|
+ * @param <T> 元素类型
|
|
|
|
+ * @return 返回该字段组成的LinkedHashSet。若元素中不存在名为fieldName的成员变量,则返回EmptySet
|
|
|
|
+ */
|
|
|
|
+ public static <T> LinkedHashSet makeLinkedSetByFieldName(Collection<T> collection, String fieldName) {
|
|
|
|
+ LinkedHashSet returnLinkedSet = new LinkedHashSet<>();
|
|
|
|
+ Iterator<T> it = collection.iterator();
|
|
|
|
+ boolean isFirst = true;
|
|
|
|
+ Field field = null;
|
|
|
|
+ while (it.hasNext()) {
|
|
|
|
+ T o = it.next();
|
|
|
|
+ if (isFirst) {
|
|
|
|
+ field = FieldUtils.getField(o.getClass(), fieldName, true);
|
|
|
|
+ if (field == null) {
|
|
|
|
+ throw new RuntimeException(o.getClass().getName() + "不存在" + fieldName);
|
|
|
|
+ }
|
|
|
|
+ isFirst = false;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ returnLinkedSet.add(field.get(o));
|
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
|
+ //ignore
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return returnLinkedSet;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将list中的元素放到Map<M, N>以建立 key - value 索引<p>
|
|
|
|
+ * modified from com.tqmall.saint.biz.util.EntityUtil#makeEntityMap(java.util.List, java.lang.String)
|
|
|
|
+ *
|
|
|
|
+ * @param collection Collection<V> 元素列表
|
|
|
|
+ * @param keyFieldName String 元素的属性名称, 该属性的值作为Map的key
|
|
|
|
+ * @param valueFieldName String 元素的属性名称, 该属性的值作为Map的value
|
|
|
|
+ * @param <M> key类型
|
|
|
|
+ * @param <N> value类型
|
|
|
|
+ * @param <V> 列表元素类型
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
+ public static <M, N, V> Map<M, N> makeMapWithKeyValue(Collection<V> collection, String keyFieldName, String valueFieldName) {
|
|
|
|
+ Map<M, N> map = new HashMap<>();
|
|
|
|
+ if (collection == null || collection.isEmpty()) {
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ Iterator<V> it = collection.iterator();
|
|
|
|
+ boolean isFirst = true;
|
|
|
|
+ Method keyGetter = null;
|
|
|
|
+ Method valueGetter = null;
|
|
|
|
+ try {
|
|
|
|
+ while (it.hasNext()) {
|
|
|
|
+ V o = it.next();
|
|
|
|
+ if (isFirst) {
|
|
|
|
+ keyGetter = getMethod(o.getClass(), keyFieldName, "get");
|
|
|
|
+ valueGetter = getMethod(o.getClass(), valueFieldName, "get");
|
|
|
|
+ isFirst = false;
|
|
|
|
+ }
|
|
|
|
+ map.put((M) keyGetter.invoke(o), (N) valueGetter.invoke(o));
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("makeEntityMap error list is " + collection, e);
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
*
|
|
*
|
|
* 将list中的元素放到Map<K, V>以建立 key - value 索引<p>
|
|
* 将list中的元素放到Map<K, V>以建立 key - value 索引<p>
|
|
@@ -45,6 +159,44 @@ public class EntityUtil {
|
|
return map;
|
|
return map;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ *
|
|
|
|
+ * 将list中的元素放到Map<String, V>以建立 key - value 索引<p>
|
|
|
|
+ *
|
|
|
|
+ * @param list List<V> 元素列表
|
|
|
|
+ * @param splitVar 属性之间间隔
|
|
|
|
+ * @param keyFieldNames String 元素的属性名称动态数组, 依次循环该属性的值作为索引key
|
|
|
|
+ * @param <V> value类型
|
|
|
|
+ * @return Map<String, V> key - value 索引
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
+ public static <V> Map<String, V> makeEntityMapByKeys(List<V> list,String splitVar , String... keyFieldNames) {
|
|
|
|
+ Map<String, V> map = new HashMap<>();
|
|
|
|
+ if(list == null || list.size() == 0 || keyFieldNames == null || keyFieldNames.length==0 || StringUtil.isEmpty(splitVar)) {
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ List<Method> getterList = new ArrayList<>();
|
|
|
|
+ for(String key : keyFieldNames){
|
|
|
|
+ getterList.add(getMethod(list.get(0).getClass(),key, "get"));
|
|
|
|
+ }
|
|
|
|
+ for (V item : list) {
|
|
|
|
+ StringBuffer keys= new StringBuffer("");
|
|
|
|
+ for (int i=0;i<getterList.size();i++){
|
|
|
|
+ keys.append(getterList.get(i).invoke(item));
|
|
|
|
+ if(i<getterList.size()-1){
|
|
|
|
+ keys.append(splitVar);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ map.put(keys.toString(), item);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("makeEntityMap error list is " + list, e);
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
/**
|
|
/**
|
|
*
|
|
*
|
|
* 将list中的元素放到Map<K, List<V>> 以建立 key - List<value> 索引<p>
|
|
* 将list中的元素放到Map<K, List<V>> 以建立 key - List<value> 索引<p>
|
|
@@ -89,4 +241,204 @@ public class EntityUtil {
|
|
String getterName = methodPrefix + fieldName.replaceFirst(first, first.toUpperCase());
|
|
String getterName = methodPrefix + fieldName.replaceFirst(first, first.toUpperCase());
|
|
return clazz.getMethod(getterName);
|
|
return clazz.getMethod(getterName);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 比较两个对象改变了的属性值,然后以string拼接返回
|
|
|
|
+ * @param oldObj 对象1
|
|
|
|
+ * @param newObj 对象2
|
|
|
|
+ * @return 改变的属性值拼接的字符串
|
|
|
|
+ */
|
|
|
|
+ public static <T> String compareToObjProperty(T oldObj,T newObj){
|
|
|
|
+ String modifiedStr = "";
|
|
|
|
+ Field[] fields = oldObj.getClass().getDeclaredFields();
|
|
|
|
+ for(Field field : fields){
|
|
|
|
+ try {
|
|
|
|
+ if(!Modifier.isStatic(field.getModifiers())){
|
|
|
|
+ String tempFieldType =field.getType().getName();
|
|
|
|
+ Method tempMethod = getMethod(oldObj.getClass(), field.getName(), "get");
|
|
|
|
+ if(field.getName().equals("ATTRIBUTE_ORDER_SN")){
|
|
|
|
+ System.out.println("aa");
|
|
|
|
+ }
|
|
|
|
+ if(tempMethod!=null){
|
|
|
|
+ Object tempOld = tempMethod.invoke(oldObj);
|
|
|
|
+ Object tempNew = tempMethod.invoke(newObj);
|
|
|
|
+ if(findDifference(tempOld,tempNew)){
|
|
|
|
+ if(tempFieldType.equals("java.util.Date")){
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd mm:HH:ss");
|
|
|
|
+ modifiedStr += field.getName() + "[" + ( tempOld == null ? null: sdf.format(tempOld)) + "," +
|
|
|
|
+ (tempNew == null ? null : sdf.format(tempNew)) + "],";
|
|
|
|
+ } else {
|
|
|
|
+ modifiedStr += field.getName()+"["+tempOld+","+ tempNew+"],";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }catch (Exception e) {
|
|
|
|
+ log.error("compareTo error", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return modifiedStr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取所有field,不包含field,修改自FieldUtils的getAllFieldsList方法
|
|
|
|
+ * @param cls 类
|
|
|
|
+ * @param forceAccess 是否包含private的field
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private static List<Field> getFieldsList(Class<?> cls, final boolean forceAccess) {
|
|
|
|
+ Validate.isTrue(cls != null, "The class must not be null");
|
|
|
|
+ final List<Field> allFields = new ArrayList<Field>();
|
|
|
|
+ Class<?> currentClass = cls;
|
|
|
|
+ final Field[] declaredFields = currentClass.getDeclaredFields();
|
|
|
|
+ for (Field field : declaredFields) {
|
|
|
|
+ if (!Modifier.isPublic(field.getModifiers())) {
|
|
|
|
+ if (forceAccess) {
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
+ } else {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ allFields.add(field);
|
|
|
|
+ }
|
|
|
|
+ return allFields;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取所有field,包含所有父类,来自FieldUtils的getAllFieldsList方法
|
|
|
|
+ * @param cls 类
|
|
|
|
+ * @param forceAccess 是否包含private的field
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private static List<Field> getAllFieldsList(Class<?> cls, final boolean forceAccess) {
|
|
|
|
+ Validate.isTrue(cls != null, "The class must not be null");
|
|
|
|
+ final List<Field> allFields = new ArrayList<Field>();
|
|
|
|
+ Class<?> currentClass = cls;
|
|
|
|
+ while (currentClass != null) {
|
|
|
|
+ final Field[] declaredFields = currentClass.getDeclaredFields();
|
|
|
|
+ for (Field field : declaredFields) {
|
|
|
|
+ if (!Modifier.isPublic(field.getModifiers())) {
|
|
|
|
+ if (forceAccess) {
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
+ } else {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ allFields.add(field);
|
|
|
|
+ }
|
|
|
|
+ currentClass = currentClass.getSuperclass();
|
|
|
|
+ }
|
|
|
|
+ return allFields;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取类型的field
|
|
|
|
+ * @param cls 类型
|
|
|
|
+ * @param checkSupers 是否要获取父类的field
|
|
|
|
+ * @param forceAccess 是否包含private的field
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private static List<Field> getFieldsList(Class<?> cls, final boolean checkSupers, final boolean forceAccess) {
|
|
|
|
+ if (checkSupers) {
|
|
|
|
+ return getAllFieldsList(cls, forceAccess);
|
|
|
|
+ } else {
|
|
|
|
+ return getFieldsList(cls, forceAccess);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 比较两个对象改变了的属性值,然后以string拼接返回
|
|
|
|
+ * @param oldObj 对象1
|
|
|
|
+ * @param newObj 对象2
|
|
|
|
+ * @param formatter 格式(默认为%s[%s,%s],第一个%s对应fieldname,第二个%对应对象1的fieldname的值,第三个%s对应对象2的fieldname的值)
|
|
|
|
+ * @param checkSupers 是否需要比较所有父类(无视继承的接口)
|
|
|
|
+ * @param forceAccess 是否需要比较private成员变量
|
|
|
|
+ * @param <T> 要比较的对象类型
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static <T> String compareToObjProperty(T oldObj, T newObj, String formatter, final boolean checkSupers, final boolean forceAccess) {
|
|
|
|
+ StringBuilder builder = new StringBuilder();
|
|
|
|
+ if (oldObj == newObj) {
|
|
|
|
+ return builder.toString();
|
|
|
|
+ }
|
|
|
|
+ if (StringUtils.isEmpty(formatter)) {
|
|
|
|
+ formatter = "%s[%s,%s]";
|
|
|
|
+ }
|
|
|
|
+ List<Field> fields = getFieldsList(oldObj.getClass(), checkSupers, forceAccess);
|
|
|
|
+ for (Field field : fields) {
|
|
|
|
+ try {
|
|
|
|
+ Object tmpOld = field.get(oldObj);
|
|
|
|
+ Object tmpNew = field.get(newObj);
|
|
|
|
+ if (findDifference(tmpOld, tmpNew)) {
|
|
|
|
+ if (field.getType().getName().equals(DATE_CLASS_NAME)) {
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd mm:HH:ss");
|
|
|
|
+ String strOld = tmpOld == null ? null : sdf.format(tmpOld);
|
|
|
|
+ String strNew = tmpNew == null ? null : sdf.format(tmpNew);
|
|
|
|
+ builder.append(String.format(formatter, field.getName(), strOld, strNew));
|
|
|
|
+ builder.append(",");
|
|
|
|
+ } else {
|
|
|
|
+ builder.append(String.format(formatter, field.getName(), tmpOld, tmpNew));
|
|
|
|
+ builder.append(",");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("compareTo error",e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return builder.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 比较两个对象的值是否不同
|
|
|
|
+ * @param obj1 对象1
|
|
|
|
+ * @param obj2 对象2
|
|
|
|
+ * @param <T> object
|
|
|
|
+ * @return 若俩对象的值不相同则为true,反之为false
|
|
|
|
+ */
|
|
|
|
+ public static <T> Boolean findDifference(T obj1,T obj2){
|
|
|
|
+ if(obj1 == null && obj2 == null){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if(obj1 == null || obj2 == null){
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ if(obj1 instanceof BigDecimal){
|
|
|
|
+ return ((BigDecimal) obj1).compareTo((BigDecimal)obj2) != 0;
|
|
|
|
+ }else {
|
|
|
|
+ return !obj1.equals(obj2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static <V,K> Map<V, K> makeEntityMapNew(List<Map<String,Object>> hashMap,String keyFieldName) {
|
|
|
|
+ Map<V, K> map = new HashMap<>();
|
|
|
|
+ if(hashMap == null || hashMap.size() == 0) {
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ for(Map linkedHashMap:hashMap){
|
|
|
|
+ map.put((V)linkedHashMap.get(keyFieldName).toString(),(K)linkedHashMap);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("makeEntityListMap error list is " + hashMap, e);
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public static Map<Integer, Map> makeEntityMapSpecial(List<Map> hashMap,String keyFieldName) {
|
|
|
|
+ Map<Integer, Map> map = new HashMap<>();
|
|
|
|
+ if(hashMap == null || hashMap.size() == 0) {
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ for(Map linkedHashMap:hashMap){
|
|
|
|
+ map.put(Integer.valueOf(linkedHashMap.get(keyFieldName).toString()),linkedHashMap);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("makeEntityListMap error list is " + hashMap, e);
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
}
|
|
}
|