'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}]


Solution 1:[1]

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.

Solution 2:[2]

Well, you could just implement a sorting algorithm that could be specialized for Gson JsonElements. 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.

Solution 3:[3]

This will return the sorted json. Used the gson library.

pass the Args: 1. jsonArray, 2. "othervarkey"

private static JsonArray JsonObjectSort(final JsonArray jsonArray, final String sortBy) {
    final JsonArray sortedArray = new JsonArray();
    final ArrayList<JsonObject> listJsonObj = new ArrayList<>();
    for (int i = 0; i < jsonArray.size(); i++) {
        listJsonObj.add((JsonObject) jsonArray.get(i));
    }

    Collections.sort(listJsonObj,
            (o1, o2) -> o1.get(sortBy).getAsString().compareToIgnoreCase(o2.get(sortBy).getAsString()));

    for (int i = 0; i < jsonArray.size(); i++) {
        sortedArray.add(listJsonObj.get(i));
    }
    return sortedArray;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Lyubomyr Shaydariv
Solution 3 Gayan Chinthaka