我有一个必须用Java解决的问题。我在YAML中有一个数据,该数据在此结构中
600450:
STATE:STATE1
CITY:CITY1
ID:1
CONTACT:1234
600453:
STATE:STATE1
CITY:CITY1
ID:2
CONTACT:3456
600451:
STATE:STATE2
CITY:CITY2
ID:3
CONTACT:2234
.....
我将其转换为JSONObject,但正在努力将其更改为结构应为这种形式的JSONObject对象
{
STATE1:
{[
CITY1:{
[{ID:1,CODE:600450,CONTACT:1234},
{ID:2,CODE:600453,CONTACT:3456}
]
},
CITY2:{
[
{ID:3,CODE:600451,CONTACT:1234}
]
}
]}
}
通过使用JSONObject和JSONArray做不同的事情,然后切换到HashMap的HashMap和ArrayList,我几乎损失了一个小时,但我无法获得它! 这是我的尝试,我确定这是荒谬的,我知道如何用Java实现。
答案 0 :(得分:0)
允许我扮演魔鬼的代言人。
我认为您可能会冒险偏离.yaml
中描述的关系。您应该尽量避免在数据模型中嵌入任何特定于应用程序的逻辑,因为您的假设将来可能会使您陷入更棘手的地方。
通常,您应该尊重数据的初始形式,并在运行时处理的灵活性下解释关系或关联的逻辑。否则,您最终将序列化与源不直接相关的数据结构,并且您的假设可能会使您陷入困境。
我怀疑是“真实的” JSON等价物;看起来像这样:
{
"600450": {
"STATE": "STATE1",
"CITY": "CITY1",
"ID": 1,
"CONTACT": 1234
},
"600453": { ...etc }
}
仍然可以配对这些关系。如果要按城市关联所有对象,则可以先将它们分成箱。您可以通过使用Map
将String
的城市与List
s的JSONObject
相关联来实现此目的:
// This will be a Map of List of JSONObjects separated by the City they belong to.
final Map<String, List<JSONObject>> mCityBins = new ArrayList();
// Iterate the List of JSONObjects.
for(final JSONObject lJSONObject : lSomeListOfJSONObjects) {
// Fetch the appropriate bin for this kind of JSONObject's city.
List<JSONObject> lBin = mCityBins.get(lJSONObject.get("city"));
// Does the right bin not exist yet?
if (lBin == null) {
// Create it!
lBin = new ArrayList();
// Make sure it is in the Map for next time!
mCityBins.add(lJSONObject.get("city"), lBin);
}
// Add the JSONObject to the selected bin.
lBin.add(lJSONObject);
}
在处理JSONObject
的同时,每当遇到Map
中不存在其密钥的城市时,您都可以分配一个新的List<JSONObject>
,并在其中添加当前项目List
并将其添加到Map
中。对于您处理的下一个JSONObject
,如果它属于同一城市,则会找到现有的List
并将其添加到其中。
一旦将它们分成垃圾箱,生成相应的JSON将很容易!
答案 1 :(得分:0)
当我看到您的git repo时,您只是尝试将第一个Json结构转换为所需的新结构。我必须告诉您,您可能可以直接从YAML文件创建此结构。 因为我没有看到您的第一个Json结构,所以我想那一定是这样的:
{600450:{STATE:STATE1 , CITY:CITY2 , ...} , ...}
如果这是真的,那么这种方式可以为您提供帮助:
public static JSONObject convert(JSONObject first) throws JSONException {
HashMap<String , HashMap<String , JSONArray>> hashMap = new HashMap<>();
Iterator<String> keys = first.keys();
while (keys.hasNext())
{
String key = keys.next();
JSONObject inner = first.getJSONObject(key);
String state = inner.getString("STATE");
HashMap<String , JSONArray> stateMap =
hashMap.computeIfAbsent(state , s -> new HashMap<>());
String city = inner.getString("CITY");
JSONArray array = stateMap.computeIfAbsent(city , s->new JSONArray());
JSONObject o = new JSONObject();
o.put("ID" , inner.getInt("ID"));
//in this section you could create int key by calling Integer.parse(String s);
o.put("CODE" , Integer.valueOf(key));
o.put("CONTACT" , inner.getInt("CONTACT"));
array.put(o);
}
JSONObject newStructureObject = new JSONObject();
for(String stateKey:hashMap.keySet())
{
JSONArray array = new JSONArray();
JSONObject cityObject = new JSONObject();
HashMap<String , JSONArray> cityMap = hashMap.get(stateKey);
for(String cityKey : cityMap.keySet())
{
cityObject.put(cityKey , cityMap.get(cityKey));
}
array.put(cityObject);
newStructureObject.put(stateKey , array);
}
return newStructureObject;
}
答案 2 :(得分:0)
假设转换后的初始JSON如下所示:
{
"600450": {
"STATE": "STATE1",
"CITY": "CITY1",
"ID": 1,
"CONTACT": 1234
},
"600451": {
"STATE": "STATE2",
"CITY": "CITY2",
"ID": 3,
"CONTACT": 2234
},
"600453": {
"STATE": "STATE1",
"CITY": "CITY1",
"ID": 2,
"CONTACT": 3456
}
}
这是一个静态方法,可以完全转换为所需的格式:
static JSONObject convert(JSONObject initial) {
// STATE -> CITY -> Address[]
Map<String, Map<String, List<Map<String, Object>>>> stateToCityToAddresses = new HashMap<>();
// Get list of codes
String[] codes = JSONObject.getNames(initial);
// Loop over codes - "600450", "600451", "600453", ...
for (String code : codes) {
// Get the JSONObject containing state data
JSONObject state = initial.getJSONObject(code);
// Extract information from state JSONObject
String stateName = state.getString("STATE");
String cityName = state.getString("CITY");
long id = state.getLong("ID");
long contact = state.getLong("CONTACT");
// Some Java 8 awesomeness!
List<Map<String, Object>> addresses = stateToCityToAddresses
.computeIfAbsent(stateName, sn -> new HashMap<>()) // This makes sure that there is a Map available to hold cities for a given state
.computeIfAbsent(cityName, cn -> new ArrayList<>()); // This makes sure that there is a List available to hold addresses for a given city
// Save data in a map representing a json object like: {"CONTACT":1234,"CODE":600450,"ID":1}
Map<String, Object> address = new HashMap<>();
address.put("ID", id);
address.put("CONTACT", contact);
address.put("CODE", Long.parseLong(code));
// Add the address under city
addresses.add(address);
}
// Just use the JSONObject.JSONObject(Map<?, ?>) constructor to get the final result
JSONObject result = new JSONObject(stateToCityToAddresses);
// You can sysout the result to see the data
// System.out.println(result);
return result;
}