當前有一個復雜對象,類似json,現在要對當前對象進行更新(已有的key更新,未有的key插入)
//遞歸更新一個json對象,原對象若沒有則插入key,精妙! @SuppressWarnings("unchecked") Object setObjectRecursive(Object current, final List<String> paths, int index, final Object value) { // 如果是已經超出path,我們就返回value即可,作為最底層葉子節點 boolean isLastIndex = index == paths.size(); if (isLastIndex) { return value; } String path = paths.get(index).trim(); boolean isNeedMap = isPathMap(path); if (isNeedMap) { Map<String, Object> mapping; // 當前不是map,因此全部替換為map,並返回新建的map對象 boolean isCurrentMap = current instanceof Map; if (!isCurrentMap) { mapping = new HashMap<String, Object>(); mapping.put( path, buildObject(paths.subList(index + 1, paths.size()), value)); return mapping; } // 當前是map,但是沒有對應的key,也就是我們需要新建對象插入該map,並返回該map mapping = ((Map<String, Object>) current); boolean hasSameKey = mapping.containsKey(path); if (!hasSameKey) { mapping.put(path,buildObject(paths.subList(index + 1, paths.size()), value)); return mapping; } // 當前是map,而且還竟然存在這個值,好吧,繼續遞歸遍歷 current = mapping.get(path); mapping.put(path, setObjectRecursive(current, paths, index + 1, value)); return mapping; } boolean isNeedList = isPathList(path); if (isNeedList) { List<Object> lists; int listIndexer = getIndex(path); // 當前是list,直接新建並返回即可 boolean isCurrentList = current instanceof List; if (!isCurrentList) { lists = expand(new ArrayList<Object>(), listIndexer + 1); lists.set( listIndexer, buildObject(paths.subList(index + 1, paths.size()), value)); return lists; } // 當前是list,但是對應的indexer是沒有具體的值,也就是我們新建對象然后插入到該list,並返回該List lists = (List<Object>) current; lists = expand(lists, listIndexer + 1); boolean hasSameIndex = lists.get(listIndexer) != null; if (!hasSameIndex) { lists.set( listIndexer, buildObject(paths.subList(index + 1, paths.size()), value)); return lists; } // 當前是list,並且存在對應的index,沒有辦法繼續遞歸尋找 current = lists.get(listIndexer); lists.set(listIndexer, setObjectRecursive(current, paths, index + 1, value)); return lists; } throw DataMException.asDataMException("該異常代表系統編程錯誤, 請聯系DataX開發團隊"); } //根據key的類型來選擇獲取value的方式 private boolean isPathMap(final String path) { return StringUtils.isNotBlank(path) && !isPathList(path); } private boolean isPathList(final String path) { return path.contains("[") && path.contains("]"); }