简体   繁体   中英

Sort JsonArray by variable key using GSON

I am trying to sort a JsonArray in Java using GSON, I would like to sort everything inside that array via a variable key, meaning there is a string somewhere containing something that is the key that the object needs to be sorted by.

Key Variable: varkey1

[{"varkey1":1,"othervarkey":1},{"varkey1":6,"othervarkey":2},{"varkey1":3,"othervarkey":3},{"varkey1":12,"othervarkey":4},{"varkey1":998,"othervarkey":5}]

So it should go like like:

[{"varkey1":1,"othervarkey":1},{"varkey1":3,"othervarkey":2},{"varkey1":6,"othervarkey":3},{"varkey1":12,"othervarkey":4},{"varkey1":998,"othervarkey":5}]

Try the following:-

String jsonListString = "[{\"varkey1\":1,\"othervarkey\":1},{\"varkey1\":6,\"othervarkey\":2},{\"varkey1\":3,\"othervarkey\":3},{\"varkey1\":12,\"othervarkey\":4},{\"varkey1\":998,\"othervarkey\":5}]";
JSONArray jsonArray = new JSONArray(jsonListString);

// Create Java ArrayList from JSON Array
ArrayList<JSONObject> array = new ArrayList<JSONObject>();
for (int i = 0; i < jsonArray.length(); i++) {
   try {
       array.add(jsonArray.getJSONObject(i));
   } catch (JSONException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}   

// Sort the Java Array List
Collections.sort(array, new Comparator<JSONObject>() {

    @Override
    public int compare(JSONObject lhs, JSONObject rhs) {
         // TODO Auto-generated method stub

        try {
            return (lhs.getInt("varkey1").compareTo(rhs.getInt("varkey1")));
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return 0;
        }
    }
});


// convert Java Array List to JSON Array and then to String representation.
jsonArray = new JSONArray(array);
jsonListString = jsonArray.toString();

This code:-

  1. Creates JSONArray from String.

  2. Creates Java ArrayList from JSONArray.

  3. Sort Java ArrayList using Collections.sort()

  4. Then Create JSONArray from Java ArrayList.

  5. Then return JSONArray as JSON String representation.

Well, you could just implement a sorting algorithm that could be specialized for Gson JsonElement s. If not, you could just re-use standard Collections.sort(...) that can merely do the job for you. For some reason, JsonArray implements Iterable and not List where the latter can be sorted with Collection.sort . So, a custom JsonArray -to- List is required:

final class JsonArrayList
        extends AbstractList<JsonElement> {

    private final JsonArray jsonArray;

    private JsonArrayList(final JsonArray jsonArray) {
        this.jsonArray = jsonArray;
    }

    static List<JsonElement> of(final JsonArray jsonArray) {
        return new JsonArrayList(jsonArray);
    }

    // This method is required when implementing AbstractList
    @Override
    public JsonElement get(final int index) {
        return jsonArray.get(index);
    }

    // This method is required when implementing AbstractList as well
    @Override
    public int size() {
        return jsonArray.size();
    }

    // And this one is required to make the list implementation modifiable
    @Override
    public JsonElement set(final int index, final JsonElement element) {
        return jsonArray.set(index, element);
    }

}

Now, the rest is simple:

// No even need of Gson instantiation
final JsonArray jsonArray = new JsonParser()
        .parse(jsonReader)
        .getAsJsonArray();
// Create a JsonArray to a List view instance
final List<JsonElement> jsonElements = JsonArrays.asList(jsonArray);
// Sorting the jsonElements object
Collections.sort(jsonElements, (e1, e2) -> {
    final int i1 = e1.getAsJsonObject().get("varkey1").getAsInt();
    final int i2 = e2.getAsJsonObject().get("varkey1").getAsInt();
    return Integer.compare(i1, i2);
});

Since the jsonElements is just a view for jsonArray , jsonArray is actually sorted.

The following example uses the Google Gson library- the only tricky part is telling the library to parse an array.

Also, defining a type (the Item class) for your json-serialized data makes it easier to interact with it via code.

package stackOv;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class JsonSort {
  public static void main(String[] args) throws Exception {
    Gson gson = new Gson();
    String json= "[{\"varkey1\":1,\"othervarkey\":1},{\"varkey1\":6,\"othervarkey\":2},{\"varkey1\":3,\"othervarkey\":3},{\"varkey1\":12,\"othervarkey\":4},{\"varkey1\":998,\"othervarkey\":5}]";
    Type listType = new TypeToken<List<Item>>(){}.getType();
    List<Item> list = gson.fromJson(json, listType);
    System.out.println( "list="+list);
    Collections.sort(list, Comparator.comparing(Item::getVarkey1));
    System.out.println( "list="+list);
  }
}

class Item {
  int varkey1;
  int othervarkey;
  public int getVarkey1() {
    return varkey1;
  }
  public void setVarkey1(int varkey) {
    this.varkey1 = varkey;
  }
  public int getOthervarkey() {
    return othervarkey;
  }
  public void setOthervarkey(int othervarkey) {
    this.othervarkey = othervarkey;
  }
  @Override
  public String toString() {
    return "Item[" + varkey1 + "," + othervarkey + "]";
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM