Android如何对JSONObjects的JSONArray进行排序
Posted
技术标签:
【中文标题】Android如何对JSONObjects的JSONArray进行排序【英文标题】:Android how to sort JSONArray of JSONObjects 【发布时间】: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 进行排序吗?
【问题讨论】:
可能被***.com/questions/4833084/…欺骗 考虑一下:如果您可以在构建 JsonArray 之前进行排序,请执行此操作。您也可以稍后在 javascript 中对其进行排序。我认为从 JsonArray 构建一个列表,对列表进行排序,然后重建 JsonArray 非常糟糕:) 【参考方案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;
【讨论】:
也许在适配器本身中这样做:***.com/a/32213875/383761【参考方案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<T>
类已经有了Insert
、Remove
、当然还有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;
【讨论】:
以上是关于Android如何对JSONObjects的JSONArray进行排序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Retrofit2 处理嵌套 JsonObjects 的动态字段
如何获取根据 JAVA 中的用户选择而变化的 JsonObjects?
如何从 JSchema/ Map JsonObjects 获取父对象名称到新父对象