やや複雑なデータマッピングの集約例とコード再構築

32288 ワード

本文の内容は真実の仕事のケースから来て、その転換は少し複雑で、しかも一定の意義があるため、記録します.
に質問
JSON列を1つ与える
{
    "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"
}

これは1つの注文の2つの商品の基本情報、価格情報および価格計算変更情報であり、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]}}

ヒント
注意深い読者は、1つの商品itemが1つのitemに対応していることを発見します.core,item_price、複数のitem_に対応する場合がありますprice_change_log .この3つのテーブルは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フィールド.
基本的な考え方は次のとおりです.
STEP 1:テーブルを含む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の実装を参照してください.
STEP 2:itemIndexMapからitem:idとitem:item_を構築core_idのマッピングitemCoreId 2 originItemIdMap;実際のアプリケーションでは、originItemIdはoldItemId(item:id)、itemCoreIdはnewItemId(item:item_core_id)である.
STEP 3:各[table:id,Map[table:field,value]]について、itemCoreId 2 origin ItemIdMapで対応するoriginitemIdを取得し、itemIndexMapで対応するitem_をoriginitemIdを使用してキーに置き換えます.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);
    }

Java 8では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);
    newItemIndexMap.get(originItemId).putAll(merge(srcMap, value));
  }

Java 8の機能
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 = "{
" + " \"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\"
" + "}"; @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);
  }

}