在遍历Java List <map <string,string =“” >>时需要建议

时间:2018-11-18 23:15:36

标签: java json java-8 iteration

我需要有关如何最好地遍历List<Map<String, String>>对象以获得以下结果的建议:

该对象保存从sql数据库获取的数据。每个Map条目仅描述返回数据的一列:

0 =
    0 =
      key = "ColumnA"
      value = "1"
    1 =
      key = "ColumnB"
      value = "2"
    2 =
      key = "ColumnC"
      value = "3"
1 =
    0 =
      key = "ColumnA"
      value = "1"
    1 =
      key = "ColumnB"
      value = "2"
    2 =
      key = "ColumnC"
      value = "3"

一个实际的数据示例如下:

0 =
    0 =
      key = "Itemtype"
      value = "1"
    1 =
      key = "Itemdate"
      value = "01.01.2018"
    2 =
      key = "Subitem"
      value = "A"
    3 =
      key = "Subitemdetail"
      value = "A"
    4 =
      key = "Subitemdetail2"
      value = "A"
1 =
    0 =
      key = "Itemtype"
      value = "1"
    1 =
      key = "Itemdate"
      value = "01.01.2018"
    2 =
      key = "Subitem"
      value = "B"
    3 =
      key = "Subitemdetail"
      value = "B"
    4 =
      key = "Subitemdetail2"
      value = "B"
2 =
    0 =
      key = "Itemtype"
      value = "2"
    1 =
      key = "Itemdate"
      value = "01.01.2018"
    2 =
      key = "Subitem"
      value = "A"
    3 =
      key = "Subitemdetail"
      value = "A"
    4 =
      key = "Subitemdetail2"
      value = "A"
3 =
    0 =
      key = "Itemtype"
      value = "2"
    1 =
      key = "Itemdate"
      value = "01.01.2018"
    2 =
      key = "Subitem"
      value = "B"
    3 =
      key = "Subitemdetail"
      value = "B"
    4 =
      key = "Subitemdetail2"
      value = "B"

当前,通过代码段以类似于JSON的格式返回数据:

  JSONArray resultSet = new JSONArray();   

  for (Map<String, String> res : data) {
      JSONObject resObject = new JSONObject();

      for (Entry<String, String> subres : res.entrySet()) {
         resObject.put(subres.getKey(), subres.getValue());
      }

     resultSet.put(resObject);
  }

上面的代码段返回以下JSON:

{
"res":[
    {
        "Itemtype": "1",
        "Itemdate": "01.01.2018",
        "Subitem": "A",
        "Subitemdetail": "A",
        "Subitemdetail2": "A"
    },
    {
        "Itemtype": "1",
        "Itemdate": "01.01.2018",
        "Subitem": "B",
        "Subitemdetail": "B",
        "Subitemdetail2": "B"
    },
    {
        "Itemtype": "2",
        "Itemdate": "01.01.2018",
        "Subitem": "A",
        "Subitemdetail": "A",
        "Subitemdetail2": "A"
    },
    {
        "Itemtype": "2",
        "Itemdate": "01.01.2018",
        "Subitem": "B",
        "Subitemdetail": "B",
        "Subitemdetail2": "B"
    }
]}

所需结果:

但是,我现在想基于Itemtype值对JSON进行分组。预期的结果如下:

{
"result":[
{
    "Itemtype": "1",
    "Itemdate": "01.01.2018",
    "Subitem": [
        {
            "Subitem": "A",
            "Subitemdetail": "A",
            "Subitemdetail2": "A"
        },
        {
            "Subitem": "B",
            "Subitemdetail": "B",
            "Subitemdetail2": "B"
        }
    ]
},
{
    "Itemtype": "2",
    "Itemdate": "01.01.2018",
    "Subitem": [
        {
            "Subitem": "A",
            "Subitemdetail": "A",
            "Subitemdetail2": "A"
        },
        {
            "Subitem": "B",
            "Subitemdetail": "B",
            "Subitemdetail2": "B"
        }
    ]
}
]}

我正在尝试寻找一种方法来最好地遍历List<Map<String, String>>对象。你能给我个建议吗?

因为我目前只能想到非常丑陋的解决方案,例如首先遍历整个对象并存储带有其位置的项目类型列表,例如上例所示: 项目1:0,1和项目2:1,2。 然后,我将遍历该列表并为自己构建JSON。但是也许您可以给我建议以寻求更好的方法?也许甚至没有Java 8流可以更好地解决该问题?

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用groupingBy流收集器获取Map,然后通过reduce将每个条目转换为所需的最终结构

类似

// Group into Itemtype -> objects Map
Map<String, List<JSONObject>> grouped = results.stream().collect(groupingBy(obj -> obj.getString("Itemtype"))

// Reduce entries into single JSON array where the Itemtype is a top level property and the entries are under Subitem
grouped.entries().stream().reduce(result, entry-> {
    JSONObject obj = new JSONObject();
    obj.putString("Itemtype", entry.getKey());
    obj.putObject("Subitem", entry.getValue());

    result.put(obj);
    return result;
}, new JSONArray())

这不能完全满足您对属性的要求,但是我相信您可以弄清楚其余部分。