【问题标题】:Android how to sort JSONArray of JSONObjectsAndroid如何对JSONObjects的JSONArray进行排序
【发布时间】:2012-10-05 18:54:52
【问题描述】:

我已经创建了一个 jsonarray 的 jsonobjects。现在我需要根据来自 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 给出错误:

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

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

【问题讨论】:

  • 考虑一下:如果您可以在构建 JsonArray 之前进行排序,请执行此操作。您也可以稍后在 JavaScript 中对其进行排序。我认为从 JsonArray 构建一个列表,对列表进行排序,然后重建 JsonArray 非常糟糕:)

标签: java android json sorting


【解决方案1】:

问题在于 JSONArray 或多或少包含最终是字符串的 JSONObject(和其他 JSONArray)。将字符串完全反序列化为 POJO,对它们进行排序,然后返回 JSON 相当繁重。

第二个问题是 JSONArray 可以包含:Boolean、JSONArray、JSONObject、Number、String 或 JSONObject.NULL 对象;即它是混合类型,因此很难将元素转储到某种类型的列表中并对其进行排序,然后通过列表将排序的项目转储回 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 中数据的同质性​​做了一些假设。如果可能,请根据您的情况进行调整。此外,您还需要添加异常处理等。祝您编码愉快!

编辑 基于 cmets 修复

【讨论】:

  • 这个例子很接近,但它不能编译。由于 Java 没有运算符重载,因此您无法以这种方式比较字符串。该示例应返回 valA.compareTo(valB)。
  • 但我想一个普通的 java 开发人员可以做到,没有谷歌或这个
  • 实际上,我在想,如果我们需要排序是为了能够比较 JSonArrays,那么应该有一种有效的方法来使用它们的哈希值来做到这一点......虽然没有尝试过,对人类来说,生成的顺序似乎是随机的。
【解决方案2】:

为了填充 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;
}

【讨论】:

【解决方案3】:

只是为了清楚上面的排序比较器代码是不正确的。 您无法像在 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);
    }
});

【讨论】:

  • 你不能直接返回 valA.compareTo(valB) 吗?
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    如果您要显示包含在JSONArray 中的数据,那么在适配器本身中对其进行排序可能是有意义的。比如ArrayAdapter&lt;T&gt;类已经有了InsertRemove、当然还有Sort等必要的方法。

    adapter.sort(new Comparator<JSONObject>(){
    
        @Override
        public int compare(JSONObject arg0, JSONObject arg1) {
    
            return arg0.optString("SortField", "").compareTo(arg1.optString("SortField","")) ;
    
        }
    
    });
    

    【讨论】:

      【解决方案6】:
      //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;
          }}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-06
        • 2013-07-15
        • 2015-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多