-1

I have this output JSON. It comes from this type List<List<TextValue>> TextValue class is String text, String value.

"data": [
  [
    {
      "text": "DescCode",
      "value": "01"
    },
    {
      "text": "DescName",
      "value": "Description 1"
    },
    {
      "text": "SecondCode",
      "value": "01"
    }
  ],
  [
    {
      "text": "DescCode",
      "value": "02"
    },
    {
      "text": "DescName",
      "value": "Description 2"
    },
    {
      "text": "SecondCode",
      "value": "02"
    }
  ]
]

I would like to transform it to this JSON out. which I believe would be this object setup. List<Map<String, String>>

"data": [
    {
      "DescCode": "01",
      "DescName": "Description 1",
      "SecondCode": "01"
    },      
    {
      "DescCode":"02",
      "DescName":"Description 2",
      "SecondCode":"02"
    }
]

My JSON is created automatically by my Spring REST controller so I really just need the Java object, Json is just for Reference. Am I off base with this? List<Map<String, String>>

Aplet123
  • 33,825
  • 1
  • 29
  • 55
howserss
  • 1,139
  • 1
  • 8
  • 12
  • Hi, you could use the stream `map` method to transform the inner `List` to a `Map`. Or if parsing from JSON a [custom deserializer](https://stackoverflow.com/questions/34176607/custom-deserialization-of-list-using-jackson/34179679) might help – IronMan Nov 17 '20 at 00:57

2 Answers2

1

Here is nested list of TextValue objects.

List<List<TextValue>> list = List.of(
        List.of(new TextValue("DescCode", "01"),
                new TextValue("DescName", "Description 1"),
                new TextValue("SecondCode", "01")),
        List.of(new TextValue("DescCode", "02"),
                new TextValue("DescName", "Description 2"),
                new TextValue("SecondCode", "02")));

And this basically streams the inner lists and then streams each of those to create a map with the specified keys and values. The maps are then collected into a list.

List<Map<String,String>> listOfMaps = list.stream()
       .map(lst->lst.stream()
        .collect(Collectors.toMap(TextValue::getText, TextValue::getValue)))
        .collect(Collectors.toList());

listOfMaps.forEach(System.out::println);

Prints

{DescName=Description 1, DescCode=01, SecondCode=01}
{DescName=Description 2, DescCode=02, SecondCode=02}

The TextValue class.

class TextValue {
    String text;
    String value;
    
    public TextValue(String text, String value) {
        this.text = text;
        this.value = value;
    }
    
    public String getText() {
        return text;
    }
    
    public String getValue() {
        return value;
    }
    
    @Override
    public String toString() {
        return String.format("%s,  %s", text, value);
    }
}
WJS
  • 36,363
  • 4
  • 24
  • 39
0

I figured it out. Loading my List<Map<String, String>> datatype was the anwser. I thought I was going to need to use some fancy stream processing but that was not necessary. Nested loops with the right objects got me there.

List<Map<String,String>> test = new ArrayList<>();
    String xmlResponseStringDesc = httpUtility.DoHttpRequest(url);
    Document doc = null;
    doc = XmlHelper.convertStringToXMLDocument(xmlResponseStringDesc);
    NodeList nodes= doc.getElementsByTagName("DescData");
    Integer i=0;

    for(int x=0;x<nodes.getLength();x++){
        Node node =nodes.item(x);
        List<Map<String, String>> nextList = new ArrayList<>();
        NodeList nodeListInner = node.getChildNodes();
        String code=node.getNodeName();
        Map<String,String> map = new HashMap<>();
        for(int y=0;y<nodeListInner.getLength();y++){
            Node nodeInner =nodeListInner.item(y);
            if(nodeInner.getTextContent().trim().equals("")){
                continue;
            }
            map.put(nodeInner.getNodeName(),nodeInner.getTextContent());
          }
        test.add(map);
    }
howserss
  • 1,139
  • 1
  • 8
  • 12