递归遍历获取复杂对象中所有目标属性的值(二)

迈不过友情╰ 2022-04-12 11:27 687阅读 0赞
  1. 在[利用递归遍历获取Java复杂对象(对象的属性仍是对象//list/map)中指定属性的值(一)][Java_list_map]中我写了递归遍历复杂对象中目标属性,找到第一个目标属性则退出遍历。现在有遇到要遍历复杂对象中所有目标属性的值。且指定了属性所在类的类名、属性类型、属性名(当然也可以不指定这些,因为我是业务需要)。另外例子对属性为List或者Map的属性的遍历做了一定改动。

现在贴代码如下(如果各位同仁发现bug,望留言告知,多谢):

两个BO类:

  1. public class PCodeTransDefPO implements Serializable {
  2. /**
  3. *
  4. */
  5. private static final long serialVersionUID = -2806783975707171326L;
  6. private String seqNo;
  7. private String srcSysCode;
  8. private String destSysCode;
  9. private String transColumnName;
  10. private String srcCodeVal;
  11. private String destCodeVal;
  12. private Timestamp procTimestamp;
  13. .........//省略了setter和getter方法

}

  1. class TestClass{
  2. private PCodeTransDefPO PCodeTransDefPO;
  3. private List<PCodeTransDefPO> arrayList = new ArrayList<>();
  4. private Map<String,PCodeTransDefPO> hashMap = new HashMap<>();
  5. public com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO getPCodeTransDefPO() {
  6. return PCodeTransDefPO;
  7. }
  8. public void setPCodeTransDefPO(com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO PCodeTransDefPO) {
  9. this.PCodeTransDefPO = PCodeTransDefPO;
  10. }
  11. public List<PCodeTransDefPO> getArrayList() {
  12. return arrayList;
  13. }
  14. public void setArrayList(List<PCodeTransDefPO> arrayList) {
  15. this.arrayList = arrayList;
  16. }
  17. public Map<String, PCodeTransDefPO> getHashMap() {
  18. return hashMap;
  19. }
  20. public void setHashMap(Map<String, PCodeTransDefPO> hashMap) {
  21. this.hashMap = hashMap;
  22. }
  23. }

递归类代码如下:

  1. package com.newcore.pcms.common.support.codetrans.codetrans;
  2. import com.newcore.pcms.common.support.codetrans.codetrans.bo.ServiceAttrDictBO;
  3. import com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import java.beans.IntrospectionException;
  7. import java.beans.PropertyDescriptor;
  8. import java.lang.reflect.Field;
  9. import java.lang.reflect.InvocationTargetException;
  10. import java.lang.reflect.Method;
  11. import java.util.ArrayList;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. /**
  16. * @author: lsl
  17. * @date: 2018/11/29
  18. */
  19. public class CodeTransHolderUtils {
  20. private static Logger logger = LoggerFactory.getLogger(CodeTransHolderUtils.class);
  21. /**
  22. * 把t中指定attribute属性的值更改为dictCode,并把没有找到dictCode的attribute放到listNotIncludeAttr
  23. * 注意:
  24. * 1、t只能是javaBean,不能是list<BO>或者Map<K,BO>
  25. * 2、t中的属性类型不能是以下类型:Set、List<Map<K,V>、Map<K,List<BO>>
  26. * 3、t中的属性类型可以是BO、数组、List<BO>、Map<K,BO>
  27. * 4、属性名一定要规范,比如private PCodeTransDefPO pCodeTransDefPO(不规范),这样利用反射找不到getter方法,应该改成codeTransDefPO或者PCodeTransDefPO
  28. */
  29. public static <T> void ergodicObject(String srcSysCode, String destSysCode, String forwardFlag, T t, String attrClass, String attrType, String attribute, List<String> listNotIncludeAttr, String dictCode) {
  30. String classType = t.getClass().getTypeName();
  31. boolean sunFlag = classType.startsWith("java.") || classType.startsWith("javax.") || classType.startsWith("org.");
  32. if (t == null || checkObjectIsSysType(t) || sunFlag) {
  33. //如果object是null/基本数据类型,或者是sun公司提供的系统类,则不需要在递归调用
  34. return;
  35. }
  36. Class clazz = t.getClass();
  37. String className = t.getClass().getSimpleName();
  38. String srcCodeVal = "";
  39. Field[] fields = clazz.getDeclaredFields();
  40. try {
  41. for (Field field : fields) {
  42. field.setAccessible(true);
  43. String proType = field.getGenericType().toString();
  44. String attrShortName = field.getName();
  45. if (attrClass.equals(className) && attrType.equals("String") && attribute.equals(attrShortName)) {
  46. // 获取object中是字典属性的值,并从数据库查询目标系统字典值,
  47. // 如果查询到目标系统字典值,把object中的字典属性值修改成目标系统的字典值,
  48. // 如果没有查询到目标系统的字典值,则把属性名添加到listNotIncludeAttr
  49. //TODO 目前暂只支持字典属性类型为String类型
  50. srcCodeVal = (String) field.get(t);
  51. String destCodeVal = "";
  52. if ("true".equals(forwardFlag)) {//调用正向码值转换方法
  53. // destCodeVal = CodeTransDefTools.queryOneByCodeTypeAndDestSys(srcCodeVal, dictCode, srcSysCode, destSysCode);
  54. destCodeVal = "ccc333";
  55. } else if ("false".equals(forwardFlag)) {//调用反向码值转换方法
  56. //TODO
  57. } else {
  58. logger.info("数据库中存储该服务的forwardFlag不正确,正确应该是(true/false),实际是forwardFlag=" + forwardFlag);
  59. }
  60. if (destCodeVal != null && !"".equals(destCodeVal)) {
  61. field.set(t, destCodeVal);
  62. } else {
  63. listNotIncludeAttr.add(attribute);
  64. logger.info("在目标系统" + destSysCode + "中,没有找到源系统" + srcSysCode + "中属性是" + attribute + "对应的字典" + dictCode + ",找到的字典值是:" + destCodeVal);
  65. }
  66. } else if ("byte".equals(proType) || "short".equals(proType) || "int".equals(proType) || "long".equals(proType) || "double".equals(proType) || "float".equals(proType) || "boolean".equals(proType)) {
  67. //属性是基本类型跳过
  68. continue;
  69. } else if ("class java.lang.Byte".equals(proType) || "class java.lang.Short".equals(proType) || "class java.lang.Integer".equals(proType) || "class java.lang.Long".equals(proType) || "class java.lang.Double".equals(proType) || "class java.lang.Float".equals(proType) || "class java.lang.Boolean".equals(proType) || ("class java.lang.String".equals(proType) && !attribute.equals(attrShortName))) {
  70. //属性是包装类跳过
  71. continue;
  72. } else if (isList(field)) {
  73. //对List/ArrayList类型的属性遍历
  74. try {
  75. PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
  76. Method method = descriptor.getReadMethod();
  77. List list = (List) method.invoke(t);
  78. if (list != null && list.size() > 0) {
  79. for (Object obj : list){
  80. // 递归
  81. ergodicObject(srcSysCode, destSysCode, forwardFlag, obj, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
  82. }
  83. }
  84. } catch (IntrospectionException e) {
  85. logger.info(e.getMessage());
  86. } catch (InvocationTargetException e) {
  87. logger.info(e.getMessage());
  88. }
  89. }else if(isMap(field)){
  90. //对Map/HashMap类型的属性遍历
  91. try {
  92. PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
  93. Method method = descriptor.getReadMethod();
  94. Map map = (Map) method.invoke(t);
  95. if (map != null && map.size() > 0) {
  96. for (Object obj : map.values()) {
  97. // 递归
  98. ergodicObject(srcSysCode, destSysCode, forwardFlag, obj, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
  99. }
  100. }
  101. } catch (IntrospectionException e) {
  102. logger.info(e.getMessage());
  103. } catch (InvocationTargetException e) {
  104. logger.info(e.getMessage());
  105. }
  106. } else if (field.getType().isArray()) {
  107. //属性是数组类型则遍历
  108. field.setAccessible(true);
  109. Object[] objArr = (Object[]) field.get(t);
  110. if (objArr != null && objArr.length > 0) {
  111. for (Object arr : objArr) {
  112. //递归
  113. ergodicObject(srcSysCode, destSysCode, forwardFlag, arr, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
  114. }
  115. }
  116. } else {
  117. //class类型的遍历
  118. try {
  119. PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), clazz);
  120. Method method = descriptor.getReadMethod();
  121. Object obj = method.invoke(t);
  122. if (obj != null) {
  123. //递归
  124. ergodicObject(srcSysCode, destSysCode, forwardFlag, obj, attrClass, attrType, attribute, listNotIncludeAttr, dictCode);
  125. } else {
  126. continue;
  127. }
  128. } catch (IntrospectionException e) {
  129. logger.info(e.getMessage());
  130. } catch (InvocationTargetException e) {
  131. logger.info(e.getMessage());
  132. }
  133. }
  134. }
  135. } catch (IllegalAccessException e) {
  136. logger.info(e.getMessage());
  137. }
  138. }
  139. /**
  140. * 判断是否是List或者ArrayList
  141. * @param field
  142. * @return
  143. */
  144. public static boolean isList(Field field){
  145. boolean flag = false;
  146. String simpleName = field.getType().getSimpleName();
  147. if ("List".equals(simpleName) || "ArrayList".equals(simpleName)){
  148. flag = true;
  149. }
  150. return flag;
  151. }
  152. /**
  153. * 判断是否是Map或者HashMap
  154. * @param field
  155. * @return
  156. */
  157. public static boolean isMap(Field field){
  158. boolean flag = false;
  159. String simpleName = field.getType().getSimpleName();
  160. if ("Map".equals(simpleName) || "HashMap".equals(simpleName)){
  161. flag = true;
  162. }
  163. return flag;
  164. }
  165. /**
  166. * 检查object是否为java的基本数据类型
  167. *
  168. * @param object
  169. * @return
  170. */
  171. public static boolean checkObjectIsSysType(Object object) {
  172. String objType = object.getClass().toString();
  173. if ("byte".equals(objType) || "short".equals(objType) || "int".equals(objType) || "long".equals(objType) || "double".equals(objType) || "float".equals(objType) || "boolean".equals(objType)) {
  174. return true;
  175. } else {
  176. return false;
  177. }
  178. }
  179. //==============================================================================================
  180. public static void main(String[] args) {
  181. PCodeTransDefPO bo = new PCodeTransDefPO();
  182. bo.setSrcSysCode("BO000");
  183. PCodeTransDefPO boList = new PCodeTransDefPO();
  184. boList.setSrcSysCode("BOList");
  185. PCodeTransDefPO boMap = new PCodeTransDefPO();
  186. boMap.setSrcSysCode("BOMap");
  187. TestClass testClass = new TestClass();
  188. List<PCodeTransDefPO> list = new ArrayList<>();
  189. list.add(boList);
  190. Map<String,PCodeTransDefPO> map = new HashMap<>();
  191. map.put("11",boMap);
  192. testClass.setPCodeTransDefPO(bo);
  193. testClass.setArrayList(list);
  194. testClass.setHashMap(map);
  195. List<String> notAttrList = new ArrayList<>();
  196. // loopObject(testClass);
  197. System.out.println("修改前,BO中的目标属性:"+ testClass.getPCodeTransDefPO().getSrcSysCode());
  198. System.out.println("修改前,List中的目标属性:"+ testClass.getArrayList().get(0).getSrcSysCode());
  199. System.out.println("修改前,Map中的目标属性:"+ testClass.getHashMap().get("11").getSrcSysCode());
  200. ergodicObject("srcsys","destsys","true",testClass,"PCodeTransDefPO","String","srcSysCode",notAttrList,"sysDictCode");
  201. System.out.println("修改后,BO中的目标属性:"+ testClass.getPCodeTransDefPO().getSrcSysCode());
  202. System.out.println("修改后,List中的目标属性:"+ testClass.getArrayList().get(0).getSrcSysCode());
  203. System.out.println("修改后,Map中的目标属性:"+ testClass.getHashMap().get("11").getSrcSysCode());
  204. }
  205. }
  206. class TestClass{
  207. private PCodeTransDefPO PCodeTransDefPO;
  208. private List<PCodeTransDefPO> arrayList = new ArrayList<>();
  209. private Map<String,PCodeTransDefPO> hashMap = new HashMap<>();
  210. public com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO getPCodeTransDefPO() {
  211. return PCodeTransDefPO;
  212. }
  213. public void setPCodeTransDefPO(com.newcore.pcms.common.support.codetrans.models.po.pcms.PCodeTransDefPO PCodeTransDefPO) {
  214. this.PCodeTransDefPO = PCodeTransDefPO;
  215. }
  216. public List<PCodeTransDefPO> getArrayList() {
  217. return arrayList;
  218. }
  219. public void setArrayList(List<PCodeTransDefPO> arrayList) {
  220. this.arrayList = arrayList;
  221. }
  222. public Map<String, PCodeTransDefPO> getHashMap() {
  223. return hashMap;
  224. }
  225. public void setHashMap(Map<String, PCodeTransDefPO> hashMap) {
  226. this.hashMap = hashMap;
  227. }
  228. }

发表评论

表情:
评论列表 (有 0 条评论,687人围观)

还没有评论,来说两句吧...

相关阅读