如何将JSON数组拆分为字符串?

3

我有一个字符串,其中包含对象的json数组,就像这样:

 [{..},{..}, ...]

我希望能将此数组中的每个对象提取为字符串。数组长度未知且对象是任意的。

一种简单的方法可能是仅在"},{"上进行拆分,但实际上这并不可行。当然,我可以将字符串反序列化为Java对象数组,然后将每个对象序列化为字符串,但这并不安全,因为最终输出可能不再与输入完全一致(这是必须的要求)。此外,性能可能会成为一个问题。

有什么想法吗?


1
为什么不使用JSON流API? - mkrakhin
不要以为那样会起作用。无法以那种方式提取未经触碰的对象字符串。 - Martin Wickman
我就是不明白为什么将字符串转换为Json对象/数组会成为一个问题... - nafas
@nafas 因为当我这样做并再次序列化时,原始字符串可能会发生变化。例如,空格或整数变成浮点数等。 - Martin Wickman
3个回答

2

好的,我有点羞于公布这段代码。它根本不是最佳选择,看起来很糟糕,但如果你想要完全不改变内容,它可能会引导你走向正确的方向。

enum ParserState {
    READING_OBJECT,
    READING_ARRAY
}


public static List<String> extractObjects(String array) throws ParseException {
    ParserState state = ParserState.READING_ARRAY;
    ArrayList<String> result = new ArrayList<String>();
    StringBuilder currentObject = null;
    int i = 0;
    int parenthesisBalance = 0;
    for (char c : array.toCharArray()) {
        switch (c) {
            case '{': {
                if (state == ParserState.READING_ARRAY) {
                    state = ParserState.READING_OBJECT;
                    currentObject = new StringBuilder();
                }
                parenthesisBalance++;
                currentObject.append(c);
                break;
            }
            case '}': {
                if (state == ParserState.READING_ARRAY) {
                    throw new ParseException("unexpected '}'", i);
                } else {
                    currentObject.append(c);
                    parenthesisBalance--;
                    if (parenthesisBalance == 0) {
                        state = ParserState.READING_ARRAY;
                        result.add(currentObject.toString());
                    }
                }
                break;
            }
            default: {
                if (state == ParserState.READING_OBJECT) {
                    currentObject.append(c);
                }
            }
        }
        i++;
    }
    return result;
}

谢谢,这个方法可行。它保留了所有条目,并且比使用gson快2倍。我会将其标记为答案,但我会使用另一个解决方案,因为它的代码更少,(恕我直言)可能经过更多测试 :-) - Martin Wickman

1

使用GSON库尝试以下代码-您还可以放置JSON对象而不是字符串LOCATION

public static void main(String[] args) {
    String obj = "{'id':'joe','ts':'2014-12-02T13:58:23.801+0100','foo':{'bar':{'v1':50019820,'v2':0,     'v3':0.001, 'v4':-100, 'v5':0.000001, 'v6':0.0, 'b':true}}}".replace("'", "\"");
    String string = String.format("[%s,%s,%s,%s]", obj , obj , obj , obj );

    JsonParser parser = new JsonParser();
    JsonArray arr = (JsonArray)parser.parse(string);

    //JsonArray arr = o.getAsJsonArray();
    Iterator<JsonElement> itr  = arr.iterator();
    while(itr.hasNext()){
        JsonElement val = itr.next();
        System.out.println(val);
    }
}

这实际上是有效的。至少gson不会干扰输出(它保留所有值完好无损)。唯一的问题是它会改变空格。不过我可以接受这个特定的问题。 - Martin Wickman

0

尝试这段代码:

public List<String> split(String jsonArray) throws Exception {
        List<String> splittedJsonElements = new ArrayList<String>();
        ObjectMapper jsonMapper = new ObjectMapper();
        JsonNode jsonNode = jsonMapper.readTree(jsonArray);

        if (jsonNode.isArray()) {
            ArrayNode arrayNode = (ArrayNode) jsonNode;
            for (int i = 0; i < arrayNode.size(); i++) {
                JsonNode individualElement = arrayNode.get(i);
                splittedJsonElements.add(individualElement.toString());
            }
        }
        return splittedJsonElements;
}

我使用了Jackson库。

希望这有所帮助!


仅翻译文本内容:以下是与编程有关的内容。返回翻译后的文本。 - mkrakhin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接