我试图对jsonarray进行排序,但出现以下错误:
Caused by: java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:895)
at java.util.TimSort.mergeAt(TimSort.java:512)
at java.util.TimSort.mergeForceCollapse(TimSort.java:453)
at java.util.TimSort.sort(TimSort.java:250)
at java.util.Arrays.sort(Arrays.java:1523)
at java.util.Collections.sort(Collections.java:238)
这是我的代码:
private JSONArray SortJSONArray(String json) {
JSONArray sortedJsonArray = new JSONArray();
try {
JSONArray jsonArr = new JSONArray(json);
List<JSONObject> jsonValues = new ArrayList<JSONObject>();
for (int i = 0; i < jsonArr.length(); i++) {
jsonValues.add(jsonArr.getJSONObject(i));
}
Collections.sort(jsonValues, new Comparator<JSONObject>() {
private static final String KEY_NAME = "EUR";
@Override
public int compare(JSONObject a, JSONObject b) {
Double valA = 0.0;
Double valB = 0.0;
try {
valA = a.getDouble(KEY_NAME);
valB = b.getDouble(KEY_NAME);
} catch (JSONException e) {
Log.e("MainActivity", e.getMessage());
}
if(valA < valB) {
return -1;
} else if( valB < valA) {
return 1;
} else {
return 0;
}
}
});
for (int i = 0; i < jsonArr.length(); i++) {
sortedJsonArray.put(jsonValues.get(i));
}
} catch (JSONException e) {
Log.e("MainActivity", e.getMessage());
}
return sortedJsonArray;
}
最佳答案
问题是a.getDouble(KEY_NAME)
或b.getDouble(KEY_NAME)
都可能引发异常。
如果a.getDouble(KEY_NAME)
抛出异常而b.getDouble(KEY_NAME)
没有,则永远不会计算b.getDouble(KEY_NAME)
,并且valA
和valB
都将保持0.0
。
另一方面,如果您比较a
并且b
是反序的(即调用compare(b,a)
而不是compare(a,b)
,则b.getDouble(KEY_NAME)
将在a.getDouble(KEY_NAME)
引发异常之前进行计算,因此valA
将是0.0
并且valB
将具有一些其他值。
在这种情况下,compare(a,b)
将返回0
,compare(b,a)
将返回一个非零值(假设b.getDouble(KEY_NAME)
不返回0.0
),这违反了Comparator
的约定。
在单独的try块中评估a.getDouble(KEY_NAME)
和b.getDouble(KEY_NAME)
将解决此问题。
try {
valA = a.getDouble(KEY_NAME);
} catch (JSONException e) {
Log.e("MainActivity", e.getMessage());
}
try {
valB = b.getDouble(KEY_NAME);
} catch (JSONException e) {
Log.e("MainActivity", e.getMessage());
}
return Double.compare(valA,valB);