简体   繁体   English

将对象JSON的2D数组反序列化为Java

[英]Deserializing 2D array of objects JSON to Java

I'm using GSON to deserialize my JSON string. 我正在使用GSON反序列化我的JSON字符串。 It seems to choke when attempting to deserialize a 2D array of objects. 尝试反序列化对象的2D数组时,似乎感到窒息。 Here's the bit: 这是位:

{ .
  ..
  ...
  "states": [
            {"SPAWNINGPHASE": [{"name": "STATEA", "duration": 4}, {"name": "STATEB", "duration": 4}]},
            {"ALIVEPHASE": [{"name": "STATEA", "duration": 5}, {"name": "STATEB", "duration": 4}]}
            ]
}

The above is a part of a bigger JSON. 上面是更大的JSON的一部分。 I get Expected BEGIN_ARRAY but was BEGIN_OBJECT I've looked over my JSON, but I don't see where it's incorrect 我得到了Expected BEGIN_ARRAY but was BEGIN_OBJECT我查看了JSON,但看不到错误的地方

Group g=gson.fromJson(configFile, Group.class);

That's what I use to start the read. 那就是我用来开始阅读的东西。 Is this not enough to process the string for the 2D array? 这还不足以处理2D数组的字符串吗?

In Group.class I tried both 在Group.class中,我都尝试了

public State[][] states;

and

public List<List<State>> states;

Everything else seems to deserialize fine. 其他一切似乎都可以反序列化。

Do I have to use this (below)? 我必须使用此(下)吗?

Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);

The JSON you show has a field states . 您显示的JSON具有字段states

That field holds an array which you show as holding two different types of objects. 该字段包含一个数组,您将其显示为包含两种不同类型的对象。 One has a field SPAWNINGPHASE , the other a field ALIVEPHASE . 一个具有SPAWNINGPHASE字段,另一个具有ALIVEPHASE字段。 Each of those hold an array that contains another type of object. 每个对象都包含一个包含另一种对象的数组。

This poses a problem for automatic deserailization to a POJO. 这给自动去反序列化到POJO带来了问题。

The only way that could possibly work is if your State class had fields for every "Phase" (This is assuming you have a Java class named NameAndDuration that you can map those inner objects to). 唯一可行的方法是,如果State类的每个“阶段”都具有字段(这是假定您有一个名为NameAndDuration的Java类,可以将这些内部对象映射到该类)。

class State {
    List<NameAndDuration> SPAWNINGPHASE;
    List<NameAndDuration> ALIVEPHASE;
    ...
}

Provided you mean that your Group class represents the JSON object, it would have: 假设您的Group类代表JSON对象,则它将具有:

List<State> states;

Gson silently ignores any missing fields in the JSON, so what you'd end up with is a List of your State objects, with only one of those fields set and all the others null . Gson默默地忽略了JSON中所有丢失的字段,因此最终得到的是State对象的List ,其中只设置了其中一个字段,所有其他字段都设置为null

As-is you would need to have: 照原样,您需要具备:

public List<Map<String, List<NameAndDuration>>> states; 

A JSON object is inherently a key/value map and since those objects inside the arrays are of a common type, that would work. JSON对象本质上是键/值映射,并且由于数组内的那些对象是通用类型,因此可以使用。 You'd have a List containing Map s that each had one entry, the "phase" as the key and a list of those inner objects. 您将拥有一个包含MapList ,每个Map都有一个条目,以“ phase”作为键,并包含这些内部对象的列表。 Not exactly ideal, but it would work. 并非完全理想,但可以正常工作。

Option B and something that makes a little more sense is changing that JSON so the "phase" is a value : 选项B和更有意义的事情是更改JSON,因此“阶段”是一个

{
    "states": [
        {
            "phase": "SPAWNINGPHASE",
            "values": [
                {
                    "name": "STATEA",
                    "duration": 4
                },
                {
                    "name": "STATEB",
                    "duration": 4
                }
            ]
        }
    ]
}

And change your State class accordingly: 并相应地更改您的State等级:

class State {
    String phase;
    List<NameAndDuration> values;
}     

(Note you could also use an enum for phase here) (请注意,您也可以在此处使用enum作为phase

Now List<State> states; 现在List<State> states; becomes a bit more usable. 变得更有用了。 (Although it does seem a bit of a misnomer; it seems like you really have a list of "phases" that contain state info rather than a list of "states") (尽管这似乎有点用词不当;似乎您确实有一个包含状态信息的“阶段”列表,而不是“状态”列表)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM