-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support equality testing #573
Comments
Please try the JSONObject and JSONArray methods Agreed that the docs need a lot of improvement. I will be getting to that. |
Thanks for the quick support and the pointer to However, since java builds a lot on top of |
Not sure what the contract of |
The contract is
Both methods are recursive and call each other as needed.
From our internal test cases using "similar" we have not had issues crop up recently, but there may be an outstanding bug we have missed. If you can provide us with your test data so we can reproduce your unexpected result, that would be appreciated. Since you are using floating point numbers from what I can see, my guess it that the failure around those comparisons. |
Agreed. It would make sense to compare numeric values by value only. |
Hi @johnjaylward thank you for the However, I can only agree with @holgerbrandl in the sense that these JSON object and array should implement a stable equals/hashCode/toString. Lots of platform types (for instance, collections) and also assertion libraries depend on a stable contract of equals/hashCode to handle equality. For JSON arrays, 2 arrays are equal if:
For JSON objects, 2 objects are equal if:
Which is the same as public boolean equals(Object other) {
return this.similar(other);
} Also hash codes should be the same if the 2 JSON arrays or objects share the same internal state. For instance: List<String> list = Arrays.asList("foo", "bar");
JSONArray a1 = JSONArray().putAll(list);
JSONArray a2 = JSONArray().putAll(list);
// this is false
boolean theSame = a1.hashCode() == a2.hashCode(); |
Our API contract that is shared with Android and maybe other implementations is that equals and hashcode are not implemented (uses base I don't see us changing this anytime soon unless it can be shown that other implementations that share the namespace/api (like Android) have also moved to implementing those methods. |
Hey! Thank you so much for getting back on this. Not sure if I am looking into the correct Android source code location, but do you mean this? https://android.googlesource.com/platform/libcore/+/android-4.4_r1.1/json/src/main/java/org/json/JSONArray.java#607 (lines 607 - 614) |
More accurately it would be here: https://android.googlesource.com/platform/libcore/+/refs/heads/master/json/src/main/java/org/json/ Due to licensing, we can not use any implementation details from that project. Or at least I'm not willing to get into that quagmire. |
A quick look shows that Android is inconsistent in their implementation. It looks like |
I see, is it for licensing reasons that the "original" can't be changed? Indeed Android is inconsistent even on JSONObject. I can't find the equals/hash on JSONObject. Just wondering how this could create Android licensing issues since this would just be a simple equals/hashCode or even a redirection to the |
for why we (likely) won't be changing the original, see the FAQ:
At this point, the library is 12+ years old (10+ on github), changing the way hashcode/equals work would be a fairly major change in how the library works. |
Licensing was not a concern for the change, only for sharing of implementation details. Android was brought up because it is the most widely known & used rewrite of this library, and we try to remain API compatible with it when possible. |
I understand. It makes sense. It might be breaking something somewhere. Thank you so much for your help @johnjaylward :) |
It would be great if the library would support
equals
forJSONObject
.An important use case would be equality/regression testing. See here for an example which hacks around the problem by using toString (which somehow works in this particular case but is certainly not good practise).
Another use case would be the use of
JSONObject
as map keys.Since there seems to be just a single data fields (
map
) inJSONObject
, it may be possible to simple delegate toHashMap.equals
. Clearly, also JSONArray would need to be equipped with anequals
(see https://stackoverflow.com/questions/4082416/equality-between-2-hashmap or https://www.baeldung.com/java-compare-hashmaps).Alternatively, the docs https://github.com/stleary/JSON-java#notes shall detail out better why an
equals
implementation can not be provided.The text was updated successfully, but these errors were encountered: