Android如何排序JSONArray的JSONObjects

时间:2012-10-15 18:27:41

标签: java android json sorting

我制作了一个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);
    }
}

然后对arraylist进行排序:

Collections.sort(db.lijst, new KreeftenComparatorLA());

或:

Collections.sort(db.lijst, new KreeftenComparatorNL());

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

Collections.sort(JA, new KreeftenComparatorNL());

Collections.sort给出错误:

  

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

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

6 个答案:

答案 0 :(得分:37)

问题是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);

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

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

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

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;    
    }
}

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

修改 根据评论修复

答案 1 :(得分: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);

在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;
}

答案 2 :(得分: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);
    }
});

答案 3 :(得分:1)

Date字段的一个示例:

public class JsonObjectComparator implements Comparator<JSONObject> {
private final String fieldName;
private Class<? extends Comparable> fieldType;

public JsonObjectComparator(String fieldName, Class<? extends Comparable> fieldType) {
    this.fieldName = fieldName;
    this.fieldType = fieldType;
}    

@Override
public int compare(JSONObject a, JSONObject b) {
    String valA, valB;
    Comparable newInstance_valA, newInstance_valB;
    int comp = 0;
    try {
        Constructor<? extends Comparable> constructor = fieldType.getConstructor(String.class);            
        valA = a.getString(fieldName);
        valB = b.getString(fieldName);
        if (fieldType.equals(Date.class)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
            newInstance_valA = dateFormat.parse(valA);            
            newInstance_valB = dateFormat.parse(valB);
        } else {
            newInstance_valA = constructor.newInstance(valA);            
            newInstance_valB = constructor.newInstance(valB);
        }
        comp = newInstance_valA.compareTo(newInstance_valB);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }

    if(comp > 0)
        return 1;
    if(comp < 0)
        return -1;
    return 0;
  }

}

public static void main(String[] args) throws JSONException {        
    JSONObject o1 = new JSONObject();
    o1.put("key1", "26-06-2014");
    JSONObject o2 = new JSONObject();
    o2.put("key1", "30-11-2011");
    JSONObject o3 = new JSONObject();
    o3.put("key1", "15-07-2014");

    JsonObjectComparator comparator = new JsonObjectComparator("key1", Date.class);
    List<JSONObject> l = new ArrayList<>();
    l.add(o1);
    l.add(o2);
    l.add(o3);

    Collections.sort(l, comparator);
 }

答案 4 :(得分:1)

如果要显示JSONArray中包含的数据,那么在适配器本身中对它进行排序可能是有意义的。例如,ArrayAdapter<T>类已经具有必要的方法,例如InsertRemove,当然还有Sort

adapter.sort(new Comparator<JSONObject>(){

    @Override
    public int compare(JSONObject arg0, JSONObject arg1) {

        return arg0.optString("SortField", "").compareTo(arg1.optString("SortField","")) ;

    }

});

答案 5 :(得分:0)

//My script
 //HEADER add final variables
    private final int TYPE_STRING = 1;
    private final int TYPE_INT = 2;
    private final int TYPE_DUBLE = 3;


//METHOD GET SORT JSONARRAY
public JSONArray  getSortJSONArray()
{
 JSONArray  json = new JSONArray  ([{"carid":"957502","vin":"XXXXX","carbrand":"CADILLAC","carmodel":"CTS","carname":"CADILLAC CTS седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carmodificationname":" седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carcolorname":"Opulent Blue Metallic - ярко-синий металлик","price":"3410000","rgb":"","volumereal":"2,00","power":"276"},{"carid":"957502","vin":"XXXXX","carbrand":"CADILLAC","carmodel":"CTS","carname":"CADILLAC CTS седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carmodificationname":" седан CTS PERFORMANC 2.0L AWD AK4 2 4WD  AT-6 276 (Л.С.)","carcolorname":"Opulent Blue Metallic - ярко-синий металлик","price":"3460000","rgb":"","volumereal":"1,00","power":"272"}]");

 /*halper - My halper */
   JSONArray sorJsonArray = halper.sort(json, getComparator("power",TYPE_INT));
   return sorJsonArray;
}

private Comparator getComparator(final String tagJSON,final int type)
    {
        Comparator c =  new Comparator()
        {
            public int compare(Object a, Object b)
            {


                try
                {
                    JSONObject    ja = (JSONObject)a;
                    JSONObject    jb = (JSONObject)b;

                    switch (type)
                    {
                        case TYPE_STRING:// String
                          return ja.optString(tagJSON, "")
                                                .toLowerCase()
                                                .compareTo(jb.optString(tagJSON, "").toLowerCase());
                        case TYPE_INT:// int
                            int valA =  ja.getInt(tagJSON);
                            int valB =  jb.getInt(tagJSON);
                            if(valA > valB)
                                return 1;
                            if(valA < valB)
                                return -1;

                        case TYPE_DUBLE:// double
                            String v1 = ja.getString(tagJSON).replace(",",".");
                            String v2 = jb.getString(tagJSON).replace(",",".");

                            double valAd = new Double(v1);// ja.getDouble(tagJSON);
                            double valBd = new Double(v2);//  jb.getDouble(tagJSON);
                            if(valAd > valBd)
                                return 1;
                            if(valAd < valBd)
                                return -1;

                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                return 0;
            }
        };

        return c;
    }

//我的Halper类

public class Halpe {
    public void Halpe(){}

    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;
    }}