获取复杂JSON对象中的键列表(Java 8)

huangapple go评论88阅读模式
英文:

Get list of keys in Complex JSON Object (Java 8)

问题

我正在处理一个看起来像这样的JSON:

{
    "key1": {
        "key1.1": {
            "nestedkey1": "something",
            "nestedkey2": "something",
            "nestedkey3": "Something"
        },
        "key1.2": {
            "nestedkey1": "something",
            "nestedkey2": "something",
            "nestedkey3": "Something"
        }
    },
    "key2": {
        "key2.1": {
            "nestedkey1": "something",
            "nestedkey2": "something",
            "nestedkey3": "Something"
        },
        "key2.2": {
            "nestedkey1": "something",
            "nestedkey2": "something",
            "nestedkey3": "Something"
        }
    }
}

我不知道所有的键。我希望获取所有的键,以便我可以创建一个Map<String, Object>。该映射应该类似于("key1" -> 相应的对象)...

在Java中是否有一种简单的方法来做到这一点?

英文:

I am dealing with a JSON that looks like this :-

{
&quot;key1&quot;: {
    &quot;key1.1&quot;: {
        &quot;nestedkey1&quot;: &quot;something&quot;,
        &quot;nestedkey2&quot;: &quot;something&quot;,
        &quot;nestedkey3&quot;: &quot;Something&quot;
    },
    &quot;key1.2&quot;: {
        &quot;nestedkey1&quot;: &quot;something&quot;,
        &quot;nestedkey2&quot;: &quot;something&quot;,
        &quot;nestedkey3&quot;: &quot;Something&quot;
    }
},
&quot;key2&quot;: {
    &quot;key2.1&quot;: {
        &quot;nestedkey1&quot;: &quot;something&quot;,
        &quot;nestedkey2&quot;: &quot;something&quot;,
        &quot;nestedkey3&quot;: &quot;Something&quot;
    },
    &quot;key2.2&quot;: {
        &quot;nestedkey1&quot;: &quot;something&quot;,
        &quot;nestedkey2&quot;: &quot;something&quot;,
        &quot;nestedkey3&quot;: &quot;Something&quot;
    }
}...

And I don't know all the keys. I wish to obtain all the keys so that I can create a Map<String, Object> out of this. That map should look something like ("key1" -> Corresponding object)...

Is there a simple way to do this in Java?

答案1

得分: 2

String filePath = "src/main/resources/json/1.json";
FileReader reader = new FileReader(filePath);

JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(reader);

Set<String> setKeys = jsonObject.keySet();
Map<String, Object> yourMap = new HashMap<>();
for (String key : setKeys) {
yourMap.put(key, jsonObject.get(key));
}

yourMap is ready!

英文:

String filePath =&quot;src/main/resources/json/1.json&quot;;
FileReader reader = new FileReader(filePath);

JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(reader);

Set&lt;String&gt; setKeys= jsonObject.keySet();
Map&lt;String,Object&gt; yourMap= new HashMap&lt;&gt;();
for (String key:setKeys) {
yourMap.put(key,jsonObject.get(key));
}

yourMap is ready!

答案2

得分: 1

使用Jackson JSON库,这个JSON可以通过TypeReference解析为Map&lt;String, Object&gt;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public class JsonTest {

    public static void main(String[] args) throws JsonProcessingException {
        String json = "..."; // JSON字符串,确保JSON有效并且有闭合的 }

        ObjectMapper mapper = new ObjectMapper();

        Map&lt;String, Object&gt; map = mapper.readValue(json, new TypeReference&lt;&gt;() {});

        System.out.println(map);
    }
}

要获取所有键的列表,需要实现一个递归方法来迭代顶层映射的条目并添加键:

public static List&lt;String&gt; getKeys(Map&lt;String, Object&gt; map) {
    List&lt;String&gt; keys = new ArrayList&lt;&gt;();
    for (Map.Entry&lt;String, Object&gt; entry : map.entrySet()) {
        keys.add(entry.getKey());
        if (entry.getValue() instanceof Map) {
            Map&lt;String, Object&gt; nested = (Map&lt;String, Object&gt;) entry.getValue();
            keys.addAll(getKeys(nested));
        }
    }
    return keys;
}

类似地,可以创建一个“前缀化”键的列表:

public static List&lt;String&gt; getPrefixedKeys(String prefix, Map&lt;String, Object&gt; map) {
    List&lt;String&gt; keys = new ArrayList&lt;&gt;();
    for (Map.Entry&lt;String, Object&gt; entry : map.entrySet()) {
        String key = prefix + entry.getKey();
        keys.add(key);
        if (entry.getValue() instanceof Map) {
            Map&lt;String, Object&gt; nested = (Map&lt;String, Object&gt;) entry.getValue();
            keys.addAll(getPrefixedKeys(key + "/", nested));
        }
    }
    return keys;
}

// 测试
System.out.println(getPrefixedKeys("/", map));

输出

[/key1, /key1/key1.1, /key1/key1.1/nestedkey1, /key1/key1.1/nestedkey2, /key1/key1.1/nestedkey3,
/key1/key1.2, /key1/key1.2/nestedkey1, /key1/key1.2/nestedkey2, /key1/key1.2/nestedkey3,
/key2, /key2/key2.1, /key2/key2.1/nestedkey1, /key2/key2.1/nestedkey2, /key2/key2.1/nestedkey3,
/key2/key2.2, /key2/key2.2/nestedkey1, /key2/key2.2/nestedkey2, /key2/key2.2/nestedkey3]
英文:

Using Jackson JSON library, this json may be parsed as a Map&lt;String, Object&gt; using TypeReference:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public class JsonTest {

    public static void main(String[] args) throws JsonProcessingException {
        String json = &quot;{\n&quot;
                + &quot;\&quot;key1\&quot;: {\n&quot;
                + &quot;    \&quot;key1.1\&quot;: {\n&quot;
                + &quot;        \&quot;nestedkey1\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey2\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey3\&quot;: \&quot;Something\&quot;\n&quot;
                + &quot;    },\n&quot;
                + &quot;    \&quot;key1.2\&quot;: {\n&quot;
                + &quot;        \&quot;nestedkey1\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey2\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey3\&quot;: \&quot;Something\&quot;\n&quot;
                + &quot;    }\n&quot;
                + &quot;},\n&quot;
                + &quot;\&quot;key2\&quot;: {\n&quot;
                + &quot;    \&quot;key2.1\&quot;: {\n&quot;
                + &quot;        \&quot;nestedkey1\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey2\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey3\&quot;: \&quot;Something\&quot;\n&quot;
                + &quot;    },\n&quot;
                + &quot;    \&quot;key2.2\&quot;: {\n&quot;
                + &quot;        \&quot;nestedkey1\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey2\&quot;: \&quot;something\&quot;,\n&quot;
                + &quot;        \&quot;nestedkey3\&quot;: \&quot;Something\&quot;\n&quot;
                + &quot;    }\n&quot;
                + &quot;}}&quot;; // make sure the json is valid and closing } is available

        ObjectMapper mapper = new ObjectMapper();

        Map&lt;String, Object&gt; map = mapper.readValue(json, new TypeReference&lt;&gt;() {});

        System.out.println(map);
    }
}

To get the list of all keys, a recursive method needs to be implemented to iterate over the entries of the top-level map and add keys:

public static List&lt;String&gt; getKeys(Map&lt;String, Object&gt; map) {
    List&lt;String&gt; keys = new ArrayList&lt;&gt;();
    for (Map.Entry&lt;String, Object&gt; entry : map.entrySet()) {
        keys.add(entry.getKey());
        if (entry.getValue() instanceof Map) {
            Map&lt;String, Object&gt; nested = (Map&lt;String, Object&gt;) entry.getValue();
            keys.addAll(getKeys(nested));
        }
    }
    return keys;
}

Similarly, a list of "prefixed" keys may be created:

public static List&lt;String&gt; getPrefixedKeys(String prefix, Map&lt;String, Object&gt; map) {
    List&lt;String&gt; keys = new ArrayList&lt;&gt;();
    for (Map.Entry&lt;String, Object&gt; entry : map.entrySet()) {
        String key = prefix + entry.getKey();
        keys.add(key);
        if (entry.getValue() instanceof Map) {
            Map&lt;String, Object&gt; nested = (Map&lt;String, Object&gt;) entry.getValue();
            keys.addAll(getPrefixedKeys(key + &quot;/&quot;, nested));
        }
    }
    return keys;
}

// test
System.out.println(getPrefixedKeys(&quot;/&quot;, map));

Output:

[/key1, /key1/key1.1, /key1/key1.1/nestedkey1, /key1/key1.1/nestedkey2, /key1/key1.1/nestedkey3, 
/key1/key1.2, /key1/key1.2/nestedkey1, /key1/key1.2/nestedkey2, /key1/key1.2/nestedkey3, 
/key2, /key2/key2.1, /key2/key2.1/nestedkey1, /key2/key2.1/nestedkey2, /key2/key2.1/nestedkey3, 
/key2/key2.2, /key2/key2.2/nestedkey1, /key2/key2.2/nestedkey2, /key2/key2.2/nestedkey3]

答案3

得分: 0

计算任务是输出无限级别的JSON记录中所有级别的字段名称。如果您尝试在Java中处理这种情况,代码会变得很长。

在SPL中进行这个操作非常方便,SPL是一个开源的Java包。只需要三行代码就足够了:

A B
1 =i=0,json(file("records.json").read())
2 func recurse(r) >i+=1,r.fno().run(tmp=eval("r.#"/~),B1=B1.to(:i-1)|r.fname(~),output(B1.concat("->")),if(ifr(tmp),func(recurse,tmp),(B1=B1|tmp)))
3 =func(recurse,A1)

SPL提供了可以被Java调用的JDBC驱动程序。只需将上述SPL脚本存储为jsonkeys.splx,并在Java中调用它,就像调用存储过程一样:


Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call jsonkeys()");
st.execute();

英文:

The computing task is to output field names of all levels in JSON records of indefinite number of levels. The code will be lengthy if you try to handle such a scenario in Java.

It is convenient to do this in SPL, the open-source Java package. Three lines of code are enough:

A B
1 =i=0,json(file("records.json").read())
2 func recurse(r) >i+=1,r.fno().run(tmp=eval("r.#"/~),B1=B1.to(:i-1)|r.fname(~),output(B1.concat("->")),if(ifr(tmp),func(recurse,tmp),(B1=B1|tmp)))
3 =func(recurse,A1)

SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as jsonkeys.splx and invoke it in Java as you call a stored procedure:

…
Class.forName(&quot;com.esproc.jdbc.InternalDriver&quot;);
con= DriverManager.getConnection(&quot;jdbc:esproc:local://&quot;);
st = con.prepareCall(&quot;call jsonkeys()&quot;);
st.execute();
…

huangapple
  • 本文由 发表于 2020年9月22日 22:06:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64011499.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定