2

我目前正在用java编写一个jsonrpc-client。请求由JSONObject表示,如下所示:

{'method': 'do.stuff', 'params': ['asdf', 3, {'foo': 'bar'}]}

现在我想实现一个低级请求缓存,为此我需要一种从 JSONObject 创建散列的方法,该散列将始终返回相同的值。使用 toString() 不是一个选项,因为 JSONObjects 是无序的:以下示例将与我的第一个示例完全相同,即使字符串表示不同:

{'params': ['asdf', 3, {'foo': 'bar'}], 'method': 'do.stuff'}

这个问题的最佳解决方案是什么?当然,jsonobject 可以嵌套到任意深度。我对 Java 很陌生,感谢任何建议。

4

4 回答 4

10

您想看看Jackson:将您的输入读取为 a JsonNode,它正确地实现.equals().hashCode()即遵守由 建立的合同java.lang.Object),适用于所有JSON 值(数字、布尔值、字符串、递归对象、递归数组、空值) .

于 2013-01-02T22:00:18.450 回答
2
I agree with @fge's solution. This is working for me across multiple variations of a JSON structure - 

    int hash = 0;
    ObjectMapper mapper = new ObjectMapper();
    JsonFactory factory = mapper.getFactory();
    try {
        JsonNode jsonNode = mapper.readTree(factory.createParser(jsonString));
        hash = jsonNode.hashCode();
    } catch (IOException e) {
        LOG.error("Error generating hash for jsonString: {}", jsonString);
        e.printStackTrace();
    }


Example permutations - 
 "{ k1: v1, k2:v2, k3: v3}"
 "{ k3: v3, k2:v2, k1: v1}"
 "{ k3: v3, k1:v1, k2: v2}"

All 3 produced same hashcode everytime. In practice however my json also had ArrayList and Map within itself and that worked perfectly well too.
于 2020-05-26T06:49:28.840 回答
0

我建议在 JSONObject 上调用 hashCode 方法,因为它不依赖于元素的顺序或字符串表示。

于 2013-01-02T22:00:27.113 回答
-4

你可以做.toString().hashCode()

即使 JSON 是无序的,我认为字符串每次都会以相同的方式生成。即使它们的生成方式不同,您的缓存中也只会有两个对象,这可能不会是世界末日。

于 2013-01-02T22:10:42.337 回答