Как могут быть в порядке пары ключей и значений во время анализа json в java, когда формат неизвестен? - PullRequest
1 голос
/ 22 апреля 2020

Имейте в виду, что структура JSON неизвестна заранее, т.е. она полностью произвольна, мы только знаем, что это формат JSON.

Например, следующая JSON

[
{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
}
  ]



Как мы можем получить данные по порядку, пока мы знаем, что HASHMAP не позаботится о порядке данных. Мы можем сделать это для обхода дерева и отслеживания того, насколько глубоко мы хотим выяснить имена свойств точечной нотации.


package samples;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ValueNode;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class FinalThing {
    public static void main(String[] args) {
        File file=new File("src/data.json");
        ObjectMapper mapper=new ObjectMapper();
        try {

            LinkedHashMap<String,String> map= new LinkedHashMap<String, String>();
            JsonNode node =mapper.readTree(file);
            getKeys("",node, map);

            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println("Key:"+entry.getKey() + ","+"   "+" value:" + entry.getValue());
            }
              } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void getKeys(String currentpath,JsonNode node,LinkedHashMap map){
        if(node.isObject()){
            ObjectNode objectNode=(ObjectNode) node;
            Iterator<Map.Entry<String, JsonNode>> it=objectNode.fields();
            String prefix=currentpath.isEmpty()?"":currentpath+".";
            while (it.hasNext()){
                SortedMap.Entry<String,JsonNode> iter=it.next();
                getKeys(prefix+iter.getKey(),iter.getValue(),map);
            }
        }else if (node.isArray()){
            ArrayNode arrayNode=(ArrayNode) node;
              for(int i=0; i<arrayNode.size(); i++){
                  getKeys(currentpath+i,arrayNode.get(i),map);
              }
        }
        else if(node.isValueNode()) {
            ValueNode valueNode=(ValueNode) node;
            map.put(currentpath,valueNode.asText());
        }
    }
}
----
but this should be in proper order because we know HashMap not take of order of data. Any alternative ways to acheive this problem.

```result
key:0.address.city, : value  Gwenborough
Key:0.address.geo.lng, : value  81.1496
Key:0.name, : value  Leanne Graham
Key:0.username, : value  Bret

1 Ответ

2 голосов
/ 22 апреля 2020

Попробуйте вместо этого использовать LinkedHashMap - он поддерживает оригинальный порядок.

...