我试图对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),并且valAvalB都将保持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)将返回0compare(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);

10-06 01:53