Android如何排序JSONArray的JSONObjects

Sim*_*mon 22 java sorting android json

我制作了一个jsonobjects的jsonarray.现在我需要根据jsonobjects中的值对JSONArray进行排序.以前我对自定义对象的ArrayLists进行了排序,如下所示:

比较:

public class KreeftenComparatorLA implements Comparator<Kreeft> {
    public int compare(Kreeft left, Kreeft right) {
        return left.latijnseNaam.compareTo(right.latijnseNaam);
    }
}
public class KreeftenComparatorNL implements Comparator<Kreeft> {
    public int compare(Kreeft left, Kreeft right) {
        return left.naam.compareTo(right.naam);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后对arraylist进行排序:

Collections.sort(db.lijst, new KreeftenComparatorLA());
Run Code Online (Sandbox Code Playgroud)

要么:

Collections.sort(db.lijst, new KreeftenComparatorNL());
Run Code Online (Sandbox Code Playgroud)

但是当我像JSONArray那样尝试同样的事情时(JA =我的jsonarray)

Collections.sort(JA, new KreeftenComparatorNL());
Run Code Online (Sandbox Code Playgroud)

Collections.sort给出错误:

类型集合中的方法sort(List,Comparator)不适用于参数(JSONArray,ThisActicity.KreeftenComparatorNL)

有人知道如何对JSONArray进行排序吗?

spe*_*ode 38

问题是JSONArray或多或少拥有最终是字符串的JSONObjects(和其他JSONArrays).将字符串完全反序列化为POJO,对它们进行排序,然后重新排序为JSON相当繁重.

第二个问题是JSONArray可以包含:Boolean,JSONArray,JSONObject,Number,String或JSONObject.NULL对象; 即它是混合类型,使得很难将元素转储到某种类型的List中并对其进行排序,然后通过列表将已排序的项目转储回JSON数组.从JSONArray中获取每个元素的通用类型的唯一方法是使用Object get()方法..当然,你所拥有的只是Object对象,如果不重新访问它们将无法对它们进行任何有意义的排序.序列化问题.

假设您的JSONArray包含同质结构化的值,您可以遍历JSONArray,在每个上调用一个类型化的get()方法,将它们转储到List类型中,然后对其进行排序.如果您的JSONArray只保留字符串或数字等"简单"类型,则相对容易.这不是确切的代码,但类似于:

List<String> jsonValues = new ArrayList<String>();
for (int i = 0; i < myJsonArray.length(); i++)
   jsonValues.add(myJsonArray.getString(i));
Collections.sort(jsonValues);
JSONArray sortedJsonArray = new JSONArray(jsonValues);
Run Code Online (Sandbox Code Playgroud)

当然,如果你有嵌套对象,这可能会有点棘手.如果你想要排在最顶层的价值,它可能不会太糟糕......

List<JSONObject> jsonValues = new ArrayList<JSONObject>();
for (int i = 0; i < myJsonArray.length(); i++)
   jsonValues.add(myJsonArray.getJSONObject(i));
Run Code Online (Sandbox Code Playgroud)

然后使用这样的比较器进行排序:

class JSONComparator implements Comparator<JSONObject>
{

    public int compare(JSONObject a, JSONObject b)
    {
        //valA and valB could be any simple type, such as number, string, whatever
        String valA = a.get("keyOfValueToSortBy");
        String valB = b.get("keyOfValueToSortBy");

        return valA.compareTo(valB);
        //if your value is numeric:
        //if(valA > valB)
        //    return 1;
        //if(valA < valB)
        //    return -1;
        //return 0;    
    }
}
Run Code Online (Sandbox Code Playgroud)

同样,这会对JSONArray中数据的同质性​​做出一些假设.如果可能,请调整您的情况.此外,您将需要添加您的异常处理等.快乐的编码!

根据评论修改编辑

  • 这个例子很接近,但它没有编译.由于Java没有运算符重载这一事实,您无法比较字符串.该示例应返回valA.compareTo(valB). (2认同)

小智 9

为了填补Android列表ArrayAdapter,我需要这样做.我就这样做了:

从JSONArray构建列表的活动代码:

JSONArray kids = node.getJSONArray("contents");
kids = JSONUtil.sort(kids, new Comparator(){
   public int compare(Object a, Object b){
      JSONObject    ja = (JSONObject)a;
      JSONObject    jb = (JSONObject)b;
      return ja.optString("name", "").toLowerCase().compareTo(jb.optString("name", "").toLowerCase();
   }
});
// in my case I wanted the original larger object contents sorted...
node.put("contents", kids);
Run Code Online (Sandbox Code Playgroud)

在JSONUtil(我的助手)中:

public static JSONArray sort(JSONArray array, Comparator c){
    List    asList = new ArrayList(array.length());
    for (int i=0; i<array.length(); i++){
      asList.add(array.opt(i));
    }
    Collections.sort(asList, c);
    JSONArray  res = new JSONArray();
    for (Object o : asList){
      res.put(o);
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)


小智 7

只是要清楚上面的代码比较器代码是不正确的.你不能像Ruby那样比较上面的字符串.这可以写得更简洁如下.否则逻辑是合理的.

Collections.sort( jsonValues, new Comparator<JSONObject>() {
    @Override
    public int compare(JSONObject a, JSONObject b) {
        String valA = new String();
        String valB = new String();

        try {
            valA = (String) a.get("keyOfValueToSortBy");
            valB = (String) b.get("keyOfValueToSortBy");
        } 
        catch (JSONException e) {
            Log.e(LOG_TAG, "JSONException in combineJSONArrays sort section", e);
        }

        return valA.compareTo(valB);
    }
});
Run Code Online (Sandbox Code Playgroud)