日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一个略复杂的数据映射聚合例子及代码重构

發布時間:2025/3/20 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个略复杂的数据映射聚合例子及代码重构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文內容來自真實的工作案例,因其轉換略復雜,且有一定意義,故記錄之。

問題

給定一個JSON串

{"item:s_id:18006666": "1024","item:s_id:18008888": "1024","item:g_id:18006666": "6666","item:g_id:18008888": "8888","item:num:18008888": "8","item:num:18006666": "6","item:item_core_id:18006666": "9876666","item:item_core_id:18008888": "9878888","item:order_no:18006666": "E20171013174712025","item:order_no:18008888": "E20171013174712025","item:id:18008888": "18008888","item:id:18006666": "18006666","item_core:num:9878888": "8","item_core:num:9876666": "6","item_core:id:9876666": "9876666","item_core:id:9878888": "9878888","item_price:item_id:1000": "9876666","item_price:item_id:2000": "9878888","item_price:price:1000": "100","item_price:price:2000": "200","item_price:id:2000": "2000","item_price:id:1000": "1000","item_price_change_log:id:1111": "1111","item_price_change_log:id:2222": "2222","item_price_change_log:item_id:1111": "9876666","item_price_change_log:item_id:2222": "9878888","item_price_change_log:detail:1111": "haha1111","item_price_change_log:detail:2222": "haha2222","item_price_change_log:id:3333": "3333","item_price_change_log:id:4444": "4444","item_price_change_log:item_id:3333": "9876666","item_price_change_log:item_id:4444": "9878888","item_price_change_log:detail:3333": "haha3333","item_price_change_log:detail:4444": "haha4444" }

這是一個訂單的兩個商品的基本信息、價格信息以及計價變更信息,是從DB里的結構獲取到的記錄。為了企業保密性,對表、字段以及值做了簡化的特殊處理。目標是將這個訂單的各個商品的信息聚合在一起。 即得到:

{1024_E20171013174712025_18006666={item:id=18006666, item_price:price=100, item_price:id=1000, item_price_change_log:id=[3333, 1111], item_core:num=6, item:g_id=6666, item:item_core_id=9876666, item_price:item_id=9876666, item:order_no=E20171013174712025, item_core:id=9876666, item_price_change_log:item_id=[9876666, 9876666], item:s_id=1024, item:num=6, item_price_change_log:detail=[haha3333, haha1111]}, 1024_E20171013174712025_18008888={item:id=18008888, item_price:price=200, item_price:id=2000, item_price_change_log:id=[2222, 4444], item_core:num=8, item:g_id=8888, item:item_core_id=9878888, item_price:item_id=9878888, item:order_no=E20171013174712025, item_price_change_log:item_id=[9878888, 9878888], item:s_id=1024, item_core:id=9878888, item:num=8, item_price_change_log:detail=[haha2222, haha4444]}}

提示

細心的讀者會發現,一個商品 item 對應一個 item_core, 一個 item_price ,可能對應多個 item_price_change_log 。這三個表都是通過 item:item_core_id 來關聯的,在 item 表是 item:item_core_id 字段, 在 item_price 表是 item_price:item_id 字段, 在 item_price_change_log 表是 item_price_change_log:item_id 字段。

基本思路是:

STEP1: 對于含有表 item, item_core, item_price, item_price_change_log 數據的指定JSON,構建一個總的 itemIndexMap[table:id, Map[table:field, value]],其中 key 是 table:id, value 是一個 valMap, valMap 的鍵是 table:field, 值是對應的最后面的值。 table: 作為名字空間的前綴,是為了避免不同表之間的ID和field相互重合覆蓋。 見方法 buildItemIndexMap 的實現。

STEP2: 從 itemIndexMap 構建 item:id 與 item:item_core_id 的映射 itemCoreId2originItemIdMap;在實際應用中, originItemId 為 oldItemId (item:id), itemCoreId 為 newItemId (item:item_core_id);

STEP3: 對于每一個 [table:id, Map[table:field, value]], 通過 itemCoreId2originItemIdMap 拿到對應的 originitemId , 然后使用 originitemId 為鍵替換itemIndexMap中對應的 item_core:id, item_price:id, item_price_change_log:id,將具有相同的 originItemId 的不同的 Map[table:field, value] 進行合并后,添加到新的newItemIndexMap 中。

程序實現

初步實現

ItemUtil.java

package zzz.study.utils;/*** Created by shuqin on 17/11/10.*/import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.util.HashMap; import java.util.Map; import java.util.Set;import static zzz.study.utils.NewMapUtil.merge;/*** Created by shuqin on 17/10/23.*/ public class ItemUtil {private static Logger logger = LoggerFactory.getLogger(ItemUtil.class);/*** 構建一個訂單的所有商品級別的信息以及映射* @param multiItemInfoMapForOneOrder 一個訂單下多個商品的信息* @return 一個訂單的所有商品級別的信息以及映射** key 是 sID + order_no + item_id ; item_id 對應 item.id, 對應 item_core.item_core_id*/public static Map<String, Map<String,Object>> buildFinalOrderItemMap(Map<String,String> multiItemInfoMapForOneOrder) {try {return mergeOrderItemMap(buildItemIndexMap(multiItemInfoMapForOneOrder));} catch (Exception ex) {logger.error("failed to buildFinalOrderItemMap for: " + multiItemInfoMapForOneOrder, ex);return new HashMap<>();}}/*** 構建一個訂單的所有商品級別的信息以及映射* @param itemInfoMap 商品級別的信息* @return 一個訂單的所有商品的信息** NOTE: itemInfoMap 是對應一個訂單的所有商品的信息的映射,不要傳多個訂單的信息進來,可能重復** key = table:table_unique_id , value = map [ table:field, value ]** eg. map [ item:goods_type:1800888 = 0 , item:num:1800888 = 8 ]* will be transformed into map[item:1800888 = map[item:goods_type=0 , item:num=8]]*/public static Map<String,Map<String,String>> buildItemIndexMap(Map<String, String> itemInfoMap) {Map<String, Map<String,String>> itemIndexMap = new HashMap<>();itemInfoMap.forEach((key, value) -> {String[] keyparts = key.split(":");// 只考慮三段式 tablename:field:idif (keyparts != null && keyparts.length == 3) {String table = keyparts[0];String field = keyparts[1];String index = keyparts[2];String indexKey = table+ ":" + index;String fieldKey = table+":"+field;if (itemIndexMap.get(indexKey) == null) {itemIndexMap.put(indexKey, new HashMap<>());}itemIndexMap.get(indexKey).put(fieldKey, String.valueOf(value));}});return itemIndexMap;}/*** 聚合一個訂單下的所有商品信息* @param itemIndexMap 一個訂單所有商品的信息映射* @return 一個訂單下的所有商品信息** key 是 sID + order_no + item_id ; item_id 對應 item.id, item_core.item_core_id*/private static Map<String, Map<String,Object>> mergeOrderItemMap(Map<String, Map<String,String>> itemIndexMap) {if (itemIndexMap == null || itemIndexMap.isEmpty()) {return new HashMap<>();}// Map[oldItemId, newItemId]Map<String,String> old2newItemIdMap = new HashMap<>();Map<String,String> new2oldItemIdMap = new HashMap<>();Set<Map.Entry<String,Map<String,String>>> entries = itemIndexMap.entrySet();String orderNo = "";String sID = "";for (Map.Entry<String,Map<String,String>> entry: entries) {String indexKey = entry.getKey();Map<String,String> value = entry.getValue();if (indexKey.startsWith("item:")) {old2newItemIdMap.put(indexKey, value.get("item:item_core_id"));new2oldItemIdMap.put(value.get("item:item_core_id"), indexKey);orderNo = value.get("item:order_no");sID = value.get("item:s_id");}}Map<String, Map<String,Object>> newItemIndexMap = new HashMap<>();for (Map.Entry<String,Map<String,String>> entry: entries) {String indexKey = entry.getKey();Map<String,String> value = entry.getValue();if (indexKey.startsWith("item:")) {if (newItemIndexMap.get(indexKey) == null) {newItemIndexMap.put(indexKey, new HashMap<>());}newItemIndexMap.get(indexKey).putAll(value);}else if (indexKey.startsWith("item_core:")) {String itemCoreId = indexKey.split(":")[1];String oldItemId = new2oldItemIdMap.get(itemCoreId);if (newItemIndexMap.get(oldItemId) == null) {newItemIndexMap.put(oldItemId, new HashMap<>());}newItemIndexMap.get(oldItemId).putAll(value);}else if (indexKey.startsWith("item_price:")) {// item_price 與 item_id 一對一關系String itemCoreId = itemIndexMap.get(indexKey).get("item_price:item_id");String oldItemId = new2oldItemIdMap.get(itemCoreId);if (newItemIndexMap.get(oldItemId) == null) {newItemIndexMap.put(oldItemId, new HashMap<>());}newItemIndexMap.get(oldItemId).putAll(value);}else if (indexKey.startsWith("item_price_change_log:")) {// item_price_change_log 與 item_id 多對一關系String itemCoreId = itemIndexMap.get(indexKey).get("item_price_change_log:item_id");String oldItemId = new2oldItemIdMap.get(itemCoreId);if (newItemIndexMap.get(oldItemId) == null) {newItemIndexMap.put(oldItemId, new HashMap<>());}Map<String,Object> srcMap = newItemIndexMap.get(oldItemId);newItemIndexMap.get(oldItemId).putAll(merge(srcMap, value));}}return buildFinalOrderItemMap(newItemIndexMap, old2newItemIdMap, orderNo, sID);}/*** 構建最終的訂單商品信息* @param itemIndexMap 商品信息* @param old2newItemIdMap 新老itemId映射* @param orderNo 訂單號* @param sID 店鋪號* @return 訂單商品擴展信息*/private static Map<String, Map<String,Object>> buildFinalOrderItemMap(Map<String, Map<String,Object>> itemIndexMap,Map<String,String> old2newItemIdMap,String orderNo, String sID) {Map<String, Map<String,Object>> finalResult = new HashMap<>();Set<Map.Entry<String,Map<String,Object>>> entries = itemIndexMap.entrySet();for (Map.Entry<String,Map<String,Object>> entry: entries) {String indexKey = entry.getKey();Map<String,Object> value = entry.getValue();String itemId = indexKey.split(":")[1];String itemKey = sID + "_" + orderNo + "_" + itemId;finalResult.put(itemKey, value);}return finalResult;}}

NewMapUtil.java

package zzz.study.utils;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;/*** Created by shuqin on 17/11/10.*/ public class NewMapUtil {/*** 將 map 的值轉為字符串類型*/public static Map<String,String> transMap(Map<String,Object> map) {if (map == null) { return null; }Map<String,String> result = new HashMap<>();map.forEach((k,v) -> result.put(k, v != null ? v.toString(): null));return result;}/*** 將兩個 Map 里相同 key 的值合并為列表** eg. src = ["id": 1, "detail": "haha111", "extra":"extra111"] ,* dest = ["id": 2, "detail": "haha222", "another": "another222"]* merge 之后返回 ["id": [1,2], "detail": ["haha111", "haha222"], "extra":"extra111", "another": "another222"]` */public static Map<String, ? extends Object> merge(Map<String,? extends Object> src, Map<String, ? extends Object> dest) {if (src == null || src.size() == 0) { return dest; }if (dest == null || dest.size() == 0) { return src; }Map<String, Object> result = new HashMap<>();src.forEach((key, value) -> {Object valueDesc = dest.get(key);if (valueDesc != null) {result.put(key, mergeToList(value, valueDesc));}else {result.put(key, value);}});dest.forEach((key, value) -> {if (result.get(key) == null) {result.put(key, value);}});return result;}public static List mergeToList(Object src, Object... args) {List valList = new ArrayList();add(valList, src);for (Object arg: args) {add(valList, arg);}return valList;}public static List add(List valList, Object src) {if (src == null) { return valList; }if (src instanceof List) {valList.addAll((List)src);}else {valList.add(src);}return valList;}}

代碼重構

可以看到,初步實現雖然實現了功能,可是代碼比較亂,尤其是 mergeOrderItemMap 方法,混雜了業務表的邏輯,理解和擴展起來比較麻煩。需要仔細重構下。另外,Map的遍歷訪問比較啰嗦,可以更簡潔一些。

使用forEach進行Map遍歷

重構從簡單做起。原來使用了

Set<Map.Entry<String,Map<String,Object>>> entries = itemIndexMap.entrySet();for (Map.Entry<String,Map<String,Object>> entry: entries) {String indexKey = entry.getKey();Map<String,Object> value = entry.getValue();String itemId = indexKey.split(":")[1];String itemKey = sID + "_" + orderNo + "_" + itemId;finalResult.put(itemKey, value);}

在 java8 中可使用 forEach 語法簡潔表達:

itemIndexMap.forEach((indexKey,value) -> {String itemId = indexKey.split(":")[1];String itemKey = sID + "_" + orderNo + "_" + itemId;finalResult.put(itemKey, value);});

抽離通用邏輯

里面有很多如下重復代碼

if (newItemIndexMap.get(oldItemId) == null) {newItemIndexMap.put(oldItemId, new HashMap<>());}newItemIndexMap.get(oldItemId).putAll(value);

實際上就是將新的item_core_id 映射成 item.id ,然后填充到新的Map,可以抽離出一個函數,然后復用。

private static void putNewIndexMap(Map<String, Map<String,Object>> newItemIndexMap,String indexKey, Map<String,String> value, Function<String, String> getOriginItemIdFunc) {String originItemId = getOriginItemIdFunc.apply(indexKey);if (newItemIndexMap.get(originItemId) == null) {newItemIndexMap.put(originItemId, new HashMap<>());}Map<String,Object> srcMap = newItemIndexMap.get(originItemId);newItemIndexMap.get(originItemId).putAll(merge(srcMap, value)); }調用: putNewIndexMap(newItemIndexMap, indexKey, value, key -> key);

配置化

看如下代碼,里面含有 item_price: , item_price:item_id 這樣的業務信息,破壞了方法的通用性。

if (indexKey.startsWith("item_price:")) {// item_price 與 item_id 一對一關系String itemCoreId = itemIndexMap.get(indexKey).get("item_price:item_id"); }

可以抽離出來做成配置。好的配置可以讓代碼大大簡化。仔細思考下整個過程:當 indexKey 包含某個表的前綴時,取它對應的 itemCoreId 的字段,然后得到 itemCoreId ,再根據 putNewIndexMap 方法將對應的 Map 添加到最終的Map中。見如下代碼:

private static Map<String,String> itemIdConf = new HashMap() {{put("item", "item:item_core_id");put("item_core", "item_core:id");put("item_price", "item_price:item_id");put("item_price_change_log", "item_price_change_log:item_id");} };String table = indexKey.split(":")[0]; if (itemIdConf.containsKey(table)) {String itemCoreIdField = itemIdConf.get(table);String itemCoreId = itemIndexMap.get(indexKey).get(itemCoreIdField);putNewIndexMap(newItemIndexMap, indexKey, value,key -> new2oldItemIdMap.get(itemCoreId)); }

哈!if-elseif-elseif 語句消失了!此時,才說真正抓住了設計重點:將itemId 的映射抽離出來做成配置,然后其它的依此解析。

重構后的ItemUtil

// 這個配置含有新老itemId映射的信息以及獲取orderNo, sID 的字段信息private static List<String>itemBaseDataConf = Arrays.asList("item:", "item:item_core_id","item:order_no", "item:s_id");private static Map<String,String> itemIdConf = new HashMap() {{put("item", "item:item_core_id");put("item_core", "item_core:id");put("item_price", "item_price:item_id");put("item_price_change_log", "item_price_change_log:item_id");}};/*** 聚合一個訂單下的所有商品信息* @param itemIndexMap 一個訂單所有商品的信息映射* @return 一個訂單下的所有商品信息** key 是 sID + order_no + item_id ;*/private static Map<String, Map<String,Object>> mergeOrderItemMap(Map<String, Map<String,String>> itemIndexMap) {if (itemIndexMap == null || itemIndexMap.isEmpty()) {return new HashMap<>();}// Map[oldItemId, newItemId]Map<String,String> old2newItemIdMap = new HashMap<>();Map<String,String> new2oldItemIdMap = new HashMap<>();Set<Map.Entry<String,Map<String,String>>> entries = itemIndexMap.entrySet();String orderNo = "";String kdtId = "";// 構建itemID映射for (Map.Entry<String,Map<String,String>> entry: entries) {String indexKey = entry.getKey();Map<String,String> value = entry.getValue();if (indexKey.startsWith(itemBaseDataConf.get(0))) {old2newItemIdMap.put(indexKey, value.get(itemBaseDataConf.get(1)));new2oldItemIdMap.put(value.get(itemBaseDataConf.get(1)), indexKey);orderNo = value.get(itemBaseDataConf.get(2));kdtId = value.get(itemBaseDataConf.get(3));}}Map<String, Map<String,Object>> newItemIndexMap = aggregationAllInfoOfEachItem(itemIndexMap, new2oldItemIdMap);return buildFinalOrderItemMap(newItemIndexMap, old2newItemIdMap, orderNo, kdtId);}/** 聚合每個商品的所有信息** Map[item:id, Map[table:field, value]]*/private static Map<String, Map<String,Object>> aggregationAllInfoOfEachItem(Map<String, Map<String,String>> itemIndexMap, Map<String,String> new2oldItemIdMap) {Map<String, Map<String,Object>> newItemIndexMap = new HashMap<>();itemIndexMap.forEach((indexKey, value) -> {String table = indexKey.split(":")[0];if (itemIdConf.containsKey(table)) {String itemCoreIdField = itemIdConf.get(table);String itemCoreId = itemIndexMap.get(indexKey).get(itemCoreIdField);putNewIndexMap(newItemIndexMap, indexKey, value,key -> new2oldItemIdMap.get(itemCoreId));}});return newItemIndexMap;}/** 將各商品信息聚合到相應的原itemId的鍵下*/private static void putNewIndexMap(Map<String, Map<String,Object>> newItemIndexMap,String indexKey, Map<String,String> value, Function<String, String> getOriginItemIdFunc) {String originItemId = getOriginItemIdFunc.apply(indexKey);if (newItemIndexMap.get(originItemId) == null) {newItemIndexMap.put(originItemId, new HashMap<>());}Map<String,Object> srcMap = newItemIndexMap.get(originItemId);newItemIndexMap.get(originItemId).putAll(merge(srcMap, value));}

Java8特性

Function

可以看到,putNewIndexMap 使用了 Function 作為參數,讓調用方指定如何去獲取 originItemId,然后根據獲取的originItemId進行通用處理。這里 Function 實現了模板方法模式。

協變

注意到這個方法簽名使用了 [ ? extends Object ]。 這里使用了協變特性。即對應參數 Map[String, ? extend Object],既可以傳入 Map[String, Object], 也可以傳入 Map[String, String] ,或 Map[String, Entity] ,避免從 Map[String, Entity] 到 Map[String, Object] 的無聊轉換。

public static Map<String, ? extends Object> merge(Map<String,? extends Object> src, Map<String, ? extends Object> dest)

單測

ItemUtilTest.java

package cc.lovesq.study.test.datastructure;import org.junit.Test;import java.util.Arrays; import java.util.Map;import cc.lovesq.study.test.CommonForTest; import zzz.study.utils.ItemUtil; import zzz.study.utils.JsonUtil; import zzz.study.utils.NewMapUtil;/*** Created by shuqin on 17/11/10.*/ public class ItemUtilTest extends CommonForTest {String newItemInfoStr = "{\n"+ " \"item:s_id:18006666\": \"1024\",\n"+ " \"item:s_id:18008888\": \"1024\",\n"+ " \"item:g_id:18006666\": \"6666\",\n"+ " \"item:g_id:18008888\": \"8888\",\n"+ " \"item:num:18008888\": \"8\",\n"+ " \"item:num:18006666\": \"6\",\n"+ " \"item:item_core_id:18006666\": \"9876666\",\n"+ " \"item:item_core_id:18008888\": \"9878888\",\n"+ " \"item:order_no:18006666\": \"E20171013174712025\",\n"+ " \"item:order_no:18008888\": \"E20171013174712025\",\n"+ " \"item:id:18008888\": \"18008888\",\n"+ " \"item:id:18006666\": \"18006666\",\n"+ " \"item_core:num:9878888\": \"8\",\n"+ " \"item_core:num:9876666\": \"6\",\n"+ " \"item_core:id:9876666\": \"9876666\",\n"+ " \"item_core:id:9878888\": \"9878888\",\n"+ " \"item_price:item_id:1000\": \"9876666\",\n"+ " \"item_price:item_id:2000\": \"9878888\",\n"+ " \"item_price:price:1000\": \"100\",\n"+ " \"item_price:price:2000\": \"200\",\n"+ " \"item_price:id:2000\": \"2000\",\n"+ " \"item_price:id:1000\": \"1000\",\n"+ " \"item_price_change_log:id:1111\": \"1111\",\n"+ " \"item_price_change_log:id:2222\": \"2222\",\n"+ " \"item_price_change_log:item_id:1111\": \"9876666\",\n"+ " \"item_price_change_log:item_id:2222\": \"9878888\",\n"+ " \"item_price_change_log:detail:1111\": \"haha1111\",\n"+ " \"item_price_change_log:detail:2222\": \"haha2222\",\n"+ " \"item_price_change_log:id:3333\": \"3333\",\n"+ " \"item_price_change_log:id:4444\": \"4444\",\n"+ " \"item_price_change_log:item_id:3333\": \"9876666\",\n"+ " \"item_price_change_log:item_id:4444\": \"9878888\",\n"+ " \"item_price_change_log:detail:3333\": \"haha3333\",\n"+ " \"item_price_change_log:detail:4444\": \"haha4444\"\n"+ "}";@Testpublic void testBuildItemIndexMapForNew() {Map<String,Object> itemInfoMap = JsonUtil.readMap(newItemInfoStr);Map<String,Map<String,String>> itemIndexMap = ItemUtil.buildItemIndexMap(NewMapUtil.transMap(itemInfoMap));System.out.println(itemIndexMap);eq("18006666", itemIndexMap.get("item:18006666").get("item:id"));eq("6666", itemIndexMap.get("item:18006666").get("item:g_id"));eq("1024", itemIndexMap.get("item:18006666").get("item:s_id"));eq("E20171013174712025", itemIndexMap.get("item:18006666").get("item:order_no"));eq("9876666", itemIndexMap.get("item:18006666").get("item:item_core_id"));eq("18008888", itemIndexMap.get("item:18008888").get("item:id"));eq("8888", itemIndexMap.get("item:18008888").get("item:g_id"));eq("1024", itemIndexMap.get("item:18008888").get("item:s_id"));eq("E20171013174712025", itemIndexMap.get("item:18008888").get("item:order_no"));eq("9878888", itemIndexMap.get("item:18008888").get("item:item_core_id"));eq("9876666", itemIndexMap.get("item_core:9876666").get("item_core:id"));eq("6", itemIndexMap.get("item_core:9876666").get("item_core:num"));eq("9878888", itemIndexMap.get("item_core:9878888").get("item_core:id"));eq("8", itemIndexMap.get("item_core:9878888").get("item_core:num"));eq("9876666", itemIndexMap.get("item_price:1000").get("item_price:item_id"));eq("1000", itemIndexMap.get("item_price:1000").get("item_price:id"));eq("100", itemIndexMap.get("item_price:1000").get("item_price:price"));eq("9878888", itemIndexMap.get("item_price:2000").get("item_price:item_id"));eq("2000", itemIndexMap.get("item_price:2000").get("item_price:id"));eq("200", itemIndexMap.get("item_price:2000").get("item_price:price"));eq("9876666", itemIndexMap.get("item_price_change_log:1111").get("item_price_change_log:item_id"));eq("haha1111", itemIndexMap.get("item_price_change_log:1111").get("item_price_change_log:detail"));eq("9878888", itemIndexMap.get("item_price_change_log:2222").get("item_price_change_log:item_id"));eq("haha2222", itemIndexMap.get("item_price_change_log:2222").get("item_price_change_log:detail"));eq("9876666", itemIndexMap.get("item_price_change_log:3333").get("item_price_change_log:item_id"));eq("haha3333", itemIndexMap.get("item_price_change_log:3333").get("item_price_change_log:detail"));eq("9878888", itemIndexMap.get("item_price_change_log:4444").get("item_price_change_log:item_id"));eq("haha4444", itemIndexMap.get("item_price_change_log:4444").get("item_price_change_log:detail"));}@Testpublic void testBuildFinalOrderItemMapForNew() {Map<String,Object> itemInfoMap = JsonUtil.readMap(newItemInfoStr);Map<String, Map<String,Object>> finalOrderItemMap = ItemUtil.buildFinalOrderItemMap(NewMapUtil.transMap(itemInfoMap));System.out.println(finalOrderItemMap);eq("18006666", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item:id"));eq("6666", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item:g_id"));eq("1024", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item:s_id"));eq("E20171013174712025", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item:order_no"));eq("9876666", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item_core:id"));eq("6", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item_core:num"));eq("9876666", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item_price:item_id"));eq("100", finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item_price:price"));eq("18008888", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item:id"));eq("8888", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item:g_id"));eq("1024", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item:s_id"));eq("E20171013174712025", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item:order_no"));eq("9878888", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item_core:id"));eq("8", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item_core:num"));eq("9878888", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item_price:item_id"));eq("200", finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item_price:price"));eq(Arrays.asList("haha3333", "haha1111"), finalOrderItemMap.get("1024_E20171013174712025_18006666").get("item_price_change_log:detail"));eq(Arrays.asList("haha2222", "haha4444"), finalOrderItemMap.get("1024_E20171013174712025_18008888").get("item_price_change_log:detail"));}}

CommonForTest.java

package cc.lovesq.study.test;import org.junit.Assert;import java.util.List;import static org.junit.Assert.assertEquals;/*** Created by shuqin on 17/11/10.*/ public class CommonForTest {public static final String NOT_THROW_EXCEPTION = "Not Throw Exception";public void eq(Object expected, Object actual) {assertEquals(expected, actual);}public <T> void eq(T[] expected, T[] actual) {Assert.assertArrayEquals(expected, actual);}public <T> void eq(List<T> expectedList, List<T> actualList) {if (expectedList == null && actualList == null) {return ;}assertEquals(expectedList.size(), actualList.size());for (int i=0; i< expectedList.size(); i++) {assertEquals(expectedList.get(i), actualList.get(i));}}public void fail(String message) {Assert.fail(message);}} package zzz.study.utils;import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize;import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map;public class JsonUtil {private static final ObjectMapper MAPPER = new ObjectMapper();static {// 為保持對象版本兼容性,忽略未知的屬性MAPPER.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);// 序列化的時候,跳過null值MAPPER.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);// date類型轉化SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");MAPPER.setDateFormat(fmt);}/*** 將一個json字符串解碼為java對象** 注意:如果傳入的字符串為null,那么返回的對象也為null** @param json json字符串* @param cls 對象類型* @return 解析后的java對象* @throws RuntimeException 若解析json過程中發生了異常*/public static <T> T toObject(String json, Class<T> cls) {if (json == null) {return null;}try {return MAPPER.readValue(json, cls);} catch (Exception e) {return null;}}/*** 讀取JSON字符串為MAP*/@SuppressWarnings("unchecked")public static Map<String, Object> readMap(String json) {return toObject(json, HashMap.class);}}

轉載于:https://www.cnblogs.com/lovesqcc/p/7812875.html

總結

以上是生活随笔為你收集整理的一个略复杂的数据映射聚合例子及代码重构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。