从通用对象

时间:2018-04-16 17:11:35

标签: java json reflection

所以我有一个Object,它可以是100个不同的特定对象中的任何一个,其中包含不同的元素,来自其他对象,列表,序列,基元等。

我想以深度优先的方式去除值,以生成一串带有分隔符的简单值。我已经映射了字段并使用递归/反射将它们存储在别处,只有在新的Object类型第一次进入时才会发生。

我是如何将数据存储在数据库中以获取一些简单示例对象的示例:

Object A layout table: Timestamp = 12345 Fields = Length|Width|Depth 
Object B layout table: Timestamp = 12345 Fields = Height|Weight|Name
Object A layout table: Timestamp = 12350 Fields = Length|Width|Depth|Label 

Object A sample: Timestamp = 12348 Values = 5|7|2 
Object A sample: Timestamp = 12349 Values = 4|3|1 
Object B sample: Timestamp = 12346 Values = 75|185|Steve Irwin
Object A sample: Timestamp = 12352 Values = 7|2|8|HelloWorld 

以下是我目前的解决方案。我正在寻求设计的改进或替代方案,以实现上述目标。

目前我使用gson.toJson()获取对象并将其转换为JSON;从那以后,我循环使用JSON来使用下面的代码获取值。问题是,这个代码对我正在开发的低端CPU非常占用CPU,因为每秒有很多样本进入。该应用程序的总体目的是将实时样本记录到SQLite数据库中的数据记录器。我还尝试将未修改的JSON存储到SQLite BLOB列中,但就DB大小而言,这是非常低效的。是否有更好/更有效的方法从对象中获取值?

我没有存储字段映射的问题,因为它只需要完成一次,但是需要对每个样本进行值剥离。我知道你也可以通过反射来做到这一点,但这也是很重要的。谁有更好的方法?

public static List<String> stripValuesFromJson(JsonElement json)
{
    // Static array list that will have the values added to it. This will
    // be the return object
    List<String> dataList = new ArrayList<String>();

    // Iterate through the JSONElement and start parsing out values
    for (Entry<String, JsonElement> entry : ((JsonObject) json).entrySet())
    {
        // Call the recursive processor that will parse out items based on their individual type: primitive, array, seq etc
        dataList.addAll(dataParser(entry.getValue()));
    }

    return dataList;
}

/**
 * The actual data processor that parses out individual values and deals with every possible type of data that can come in.
 * 
 * @param json - The json object being recursed through
 * @return - return the list of values
 */
public static List<String> dataParser(JsonElement json)
{
    List<String> dataList = new ArrayList<String>();

    // Deal with primitives
    if (json instanceof JsonPrimitive)
    {
        // Deal with items that come up as true/false.
        if (json.getAsString().equals("false"))
        {
            dataList.add("0");
        } else if (json.getAsString().equals("true"))
        {
            dataList.add("1");
        } else
        {
            dataList.add(json.getAsString());
        }
        // Send through recursion to get the primitives or objects out of this object
    } else if (json instanceof JsonObject)
    {
        dataList.addAll(stripValuesFromJson(json));
    } else if (json instanceof JsonArray)
    {
        // Send through recursion for each element in this array/sequence
        for (JsonElement a : (JsonArray) json)
        {
            dataList.addAll(dataParser(a));
        }
    } else if (json instanceof JsonNull)
    {
        dataList.add(null);
    } else
    {
        errorLog.error("Unknown JSON type: " + json.getClass());
    }

    return dataList;
}

1 个答案:

答案 0 :(得分:0)

您可以尝试的一件事是编写自己的JSON解析器,它只是发出值。我在JavaCC有更多经验,因此我采用one of existing JSON语法并对其进行修改,使其仅输出值。这不应该太复杂 以mentioned grammar

中的booleanValue作品为例
Boolean booleanValue(): {
    Boolean b;
}{
    (
        (
            <TRUE>
            { b = Boolean.TRUE; }
        ) | (
            <FALSE>
            { b = Boolean.FALSE; }
        )   
    )
    { return b; }
}

基本上,你需要替换返回布尔值并将"1""0"附加到目标列表。

ANTLR是另一种选择。