我制作了一个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进行排序吗?
答案 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>
类已经具有必要的方法,例如Insert
,Remove
,当然还有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;
}}