歡迎光臨
每天分享高質量文章

Java8 Map 示例:一個略複雜的資料對映聚合例子及程式碼重構

(點選上方公眾號,可快速關註)


來源:琴水玉,

www.cnblogs.com/lovesqcc/p/7812875.html

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

問題

給定一個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> buildFinalOrderItemMap(Map 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> buildItemIndexMap(Map itemInfoMap) {

    Map> itemIndexMap = new HashMap<>();

 

    itemInfoMap.forEach(

        (key, value) -> {

          String[] keyparts = key.split(“:”);

 

          // 只考慮三段式 tablename:field:id

          if (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> mergeOrderItemMap(Map> itemIndexMap) {

 

    if (itemIndexMap == null || itemIndexMap.isEmpty()) {

      return new HashMap<>();

    }

 

    // Map[oldItemId, newItemId]

    Map old2newItemIdMap = new HashMap<>();

    Map new2oldItemIdMap = new HashMap<>();

 

    Set>> entries = itemIndexMap.entrySet();

    String orderNo = “”;

    String sID = “”;

    for (Map.Entry> entry: entries) {

      String indexKey = entry.getKey();

      Map 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> newItemIndexMap = new HashMap<>();

 

    for (Map.Entry> entry: entries) {

      String indexKey = entry.getKey();

      Map 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 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> buildFinalOrderItemMap(Map> itemIndexMap,

                                                                        Map old2newItemIdMap,

                                                                        String orderNo, String sID) {

    Map> finalResult = new HashMap<>();

 

    Set>> entries = itemIndexMap.entrySet();

 

    for (Map.Entry> entry: entries) {

      String indexKey = entry.getKey();

      Map 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 transMap(Map map) {

    if (map == null) { return null; }

    Map 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 merge(Map src, Map dest) {

    if (src == null || src.size() == 0) { return dest; }

    if (dest == null || dest.size() == 0) { return src; }

 

    Map 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>> entries = itemIndexMap.entrySet();

 

    for (Map.Entry> entry: entries) {

      String indexKey = entry.getKey();

      Map 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> newItemIndexMap,

                                     String indexKey, Map value, Function getOriginItemIdFunc) {

    String originItemId = getOriginItemIdFunc.apply(indexKey);

    if (newItemIndexMap.get(originItemId) == null) {

      newItemIndexMap.put(originItemId, new HashMap<>());

    }

    Map 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 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

      itemBaseDataConf = Arrays.asList(“item:”, “item:item_core_id”,

                                       “item:order_no”, “item:s_id”);

 

  private static Map 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> mergeOrderItemMap(Map> itemIndexMap) {

 

    if (itemIndexMap == null || itemIndexMap.isEmpty()) {

      return new HashMap<>();

    }

 

    // Map[oldItemId, newItemId]

    Map old2newItemIdMap = new HashMap<>();

    Map new2oldItemIdMap = new HashMap<>();

 

    Set>> entries = itemIndexMap.entrySet();

    String orderNo = “”;

    String kdtId = “”;

 

    // 構建itemID對映

    for (Map.Entry> entry: entries) {

      String indexKey = entry.getKey();

      Map 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> newItemIndexMap = aggregationAllInfoOfEachItem(itemIndexMap, new2oldItemIdMap);

    return buildFinalOrderItemMap(newItemIndexMap, old2newItemIdMap, orderNo, kdtId);

 

  }

 

  /*

   * 聚合每個商品的所有資訊

   *

   * Map[item:id, Map[table:field, value]]

   */

  private static Map> aggregationAllInfoOfEachItem(Map> itemIndexMap, Map new2oldItemIdMap) {

 

    Map> 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> newItemIndexMap,

                                     String indexKey, Map value, Function getOriginItemIdFunc) {

    String originItemId = getOriginItemIdFunc.apply(indexKey);

    if (newItemIndexMap.get(originItemId) == null) {

      newItemIndexMap.put(originItemId, new HashMap<>());

    }

    Map srcMap = newItemIndexMap.get(originItemId);

    newItemI

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 merge(Map src, Map 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”

                          + “}”;

 

  @Test

  public void testBuildItemIndexMapForNew() {

    Map itemInfoMap = JsonUtil.readMap(newItemInfoStr);

    Map> 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”));

  }

 

  @Test

  public void testBuildFinalOrderItemMapForNew() {

    Map itemInfoMap = JsonUtil.readMap(newItemInfoStr);

    Map> 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 void eq(T[] expected, T[] actual) {

    Assert.assertArrayEquals(expected, actual);

  }

 

  public void eq(List expectedList, List 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 toObject(String json, Class cls) {

    if (json == null) {

      return null;

    }

    try {

      return MAPPER.readValue(json, cls);

    } catch (Exception e) {

      return null;

    }

  }

 

  /**

   * 讀取JSON字串為MAP

   */

  @SuppressWarnings(“unchecked”)

  public static Map readMap(String json) {

    return toObject(json, HashMap.class);

  }

 

}

看完本文有收穫?請轉發分享給更多人

關註「ImportNew」,提升Java技能

贊(0)

分享創造快樂