I'm currently writing a jsonrpc-client in java. A request is represented by an JSONObject like this:
{'method': 'do.stuff', 'params': ['asdf', 3, {'foo': 'bar'}]}
Now I want to implement a low-level request cache and for this I need a way to create a hash from a JSONObject that will always return the same value. Using the toString() is not an option since JSONObjects are unordered: the following example would do exactly the same as my first example even though the string representation is different:
{'params': ['asdf', 3, {'foo': 'bar'}], 'method': 'do.stuff'}
Whats the best solution to this problem? The jsonobject may be nested to any arbitrary depth of course. I'm fairly new to Java and thankful for any suggestion.
You want to have a look at Jackson: read your input as a JsonNode, which implements .equals() and .hashCode() correctly (that is, sticking to the contract established by java.lang.Object), for all JSON values (numbers, booleans, strings, objects recursively, arrays recursively, nulls).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With