Skip to content

Commit 9ed1c18

Browse files
committed
Fix Java comparator symmetry. #114
Java sort enforces compare symmetry: sgn(compare(x, y)) == -sgn(compare(y, x)) This is not mandatory for the Jsonata comparator, and produces the error ("violates general contract") if it doesn't. This change ensures Java compare symmetry. Runtime complexity remains O(2) == O(1). Fixes original unit tests (2 test overrides removed) and the sorting test data provided.
1 parent bf8ec3a commit 9ed1c18

2 files changed

Lines changed: 4 additions & 12 deletions

File tree

src/main/java/com/dashjoin/jsonata/Functions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,15 +1959,17 @@ public static List sort(List arr, Object comparator) {
19591959
public int compare(Object o1, Object o2) {
19601960
try {
19611961
Boolean swap = toBoolean(funcApply(comparator, Arrays.asList(o1, o2)));
1962+
// Symmetry/equality: if Jsonata comp(o1,o2)==comp(o2,o1) means Java o1==o2 (return 0)
1963+
Boolean swapSym = toBoolean(funcApply(comparator, Arrays.asList(o2, o1)));
1964+
if (swap != null && swap.equals(swapSym))
1965+
return 0;
19621966
if (swap == null)
19631967
return 0;
19641968
if (swap)
19651969
return 1;
19661970
else
19671971
return -1;
19681972
} catch (Throwable e) {
1969-
// TODO Auto-generated catch block
1970-
//e.printStackTrace();
19711973
throw new RuntimeException(e);
19721974
}
19731975
}

test/test-overrides.json

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,6 @@
130130
"alternateResult": "1e+20",
131131
"reason": "toString precision should be 15, handled differently by Java Bigdecimal(..., new MathContext(15)"
132132
},
133-
{
134-
"name": "function-sort/case009.json",
135-
"alternateResult": ["0406634348", "040657863", "0406654608", "0406654603"],
136-
"reason": "the sort expression is evaluated correctly - however the sort algorithm seems to behave slightly different for equality - jsonata expects the native order to be preserved"
137-
},
138-
{
139-
"name": "function-sort/case010.json",
140-
"alternateResult": ["0406634348", "0406654608", "040657863", "0406654603"],
141-
"reason": "same as above, works if the condition is changed to >="
142-
},
143133
{
144134
"name": "function-applications/case008.json",
145135
"ignoreError": true,

0 commit comments

Comments
 (0)