(Java)使用Java8将JSONObject的JSONArray扁平化为[[]]

时间:2017-04-18 20:18:19

标签: java arrays json java-8

我正在使用net.sf.json.JSONArray和net.sf.json.JSONObject。 JSONArray包含多个JSONObject。

基本上这个:

[
    {
        "obj1": [
            {
                "ID": 12
                "NAME":"Whatever",
                "XY":[1,2]
            },
            {
                "ID": 34
                "NAME":"Again",
                "XY":[23,43]
            },
            etc
        ]
    },
    { "obj2": repeat}
]

我想用Java 8压扁它,即结果:

[
    {
        "obj1": [
                    [12,'Whatever',1,2],
                    [34,'Again',23,43],
                    etc...
        ]
    },
    { "obj2": repeat}
]

2 个答案:

答案 0 :(得分:2)

尽管你可以用命令式的方式很容易地实现这一点,但是在递归中它可能更容易实现。我不确定我是否擅长Java 8中的惯用功能代码,但您需要:

  • 将项目收集到单个数组的收集器
static Collector<Object, JSONArray, JSONArray> toJSONArray() {
    return Collector.of(
            JSONArray::new,     // Create a new array
            JSONArray::add,     // Add each element to the target array
            (a1, a2) -> {       // Merge the second array into the first one
                a1.addAll(a2);
                return a1;
            },
            identity()          // Return the populated array itself
    );
}
static Stream<?> flatten(final Object value) {
    return value instanceof Collection
            ? ((Collection<?>) value).stream().flatMap(Q43481457::flatten) // Flatten recursively
            : Stream.of(value);                                            // Otherwise wrap a single element into a stream
}
  • 主要代码:
@SupressWarnings("unchecked")
final Collection<JSON> jsonArray = (Collection<JSON>) originalJsonArray;
final JSONArray flatJSONArray = jsonArray.stream()
        .map(json -> (Map<?, ?>) json)          // All outer array elements are JSON objects and maps in particular
        .map(jsonObject -> jsonObject.values()  // Recursively flatten the JSON object values
                .stream()
                .flatMap(Q43481457::flatten)
                .collect(toJSONArray())         // ... collecting them to JSON arrays
        )
        .collect(toJSONArray());                // ... which are collected to JSON arrays
System.out.println(flatJSONArray);

输出:

  

[[12,&#34;无论&#34;,1,2],[34,&#34;再次&#34;,23,43]

答案 1 :(得分:0)

用法

JSONArray array = ...;
JSONArray flattedArray = flatten(array);

JSONObject map = ...;
JSONObject flattedMap = flatten(map);

实施

当json结构发生变化时,实现经历了巨大的变化,您可以在github上比较我的提交历史记录。并且tests可以告诉您我如何实现您的功能。

public JSONArray flatten(Collection<?> array) {
    return array.stream().flatMap(this::flatting).collect(toJSONArray());
}

private Stream<?> flatting(Object it) {
    if (it instanceof Collection) {
        return ((Collection<?>) it).stream();
    }
    if (it instanceof Map) {
        return Stream.of(flatten((Map<?, ?>) it));
    }
    return Stream.of(it);
}

public JSONObject flatten(Map<?, ?> map) {
    return map.entrySet().stream().collect(
            JSONObject::new,
            (it, field) -> it.put(field.getKey(), flatten(field.getValue())),
            JSONObject::putAll
    );
}

private Object flatten(Object it) {
    if (it instanceof Collection) {
        return ((Collection<?>) it).stream().map(this::flatten)
                                            .collect(toJSONArray());
    }
    if (it instanceof Map) {
        return flatten(((Map<?, ?>) it).values());
    }
    return it;
}

private <T> Collector<T, ?, JSONArray> toJSONArray() {
    return toCollection(JSONArray::new);
}