3

i have two json objects in jsonarray like this

"errorCode": "1",
"data": [
    {
        "messageId": 590,
        "message": "WvZiT3RPm7feC6Hxsa/Ing==",
        "messageType": "CHAT",
        "sentOn": "01:51 PM, Apr 06, 2013",

        "mainParent": 589,
        "officeId": "19",
        "webParent": 590
    },
    {
        "messageId": 589,
        "message": "1A45rtoC3Cy88h73TEvDqQ==",
        "messageType": "CHAT",
        "sentOn": "01:50 PM, Apr 06, 2013",

        "parent": 0,
        "signImg": null,
        "mainParent": 589,
        "officeId": "19",
        "webParent": 1
    }
]

so i want to sort in ascending order based on message id key. i tried with comparator with object type as json object, i am getting error in compareto method. please suggest me

5
  • You're trying to do this the hardway. Either do it before you convert to JSON (if you're generating this), or after converting from JSON to java objects (as you aren't keeping all this as JSON, I'm sure- you're parsing it into objects at some point for ease of coding, right?). Doing it while its JSON is just painful. Commented Apr 6, 2013 at 20:21
  • @GabeSechan the way I read the question, I suspect he is using a JSON library and trying to manipulate the JSON DOM. @user2014616 please post your Comparator code and the error you run into. Commented Apr 6, 2013 at 20:25
  • before converting to json is there any way to sort Commented Apr 6, 2013 at 21:05
  • public class SortBasedOnMessageId implements Comparator<JSONObject> { @Override public int compare(JSONObject lhs, JSONObject rhs) { if (rhs.getInt("messageId") <lhs.getInt("messageId")) return -1; else if (rhs.getInt("messageId") >lhs.getInt("messageId")) return 1; else return 0; } } Commented Apr 6, 2013 at 21:06
  • this will help you to solve the issue Commented Jun 4, 2013 at 10:00

3 Answers 3

10

I am posting the answer here helping others who are facing the issue with this kind of problems.

public static JSONArray getSortedList(JSONArray array) throws JSONException {
            List<JSONObject> list = new ArrayList<JSONObject>();
            for (int i = 0; i < array.length(); i++) {
                    list.add(array.getJSONObject(i));
            }
            Collections.sort(list, new SortBasedOnMessageId());

            JSONArray resultArray = new JSONArray(list);

            return resultArray;
}

This part of the code will help to sort the json array

Check out the SortBasedOnMessageId class below.

public class SortBasedOnMessageId implements Comparator<JSONObject> {
    /*
    * (non-Javadoc)
    * 
    * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
    * lhs- 1st message in the form of json object. rhs- 2nd message in the form
    * of json object.
    */
    @Override
    public int compare(JSONObject lhs, JSONObject rhs) {
        try {
            return lhs.getInt("messageId") > rhs.getInt("messageId") ? 1 : (lhs
                .getInt("messageId") < rhs.getInt("messageId") ? -1 : 0);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return 0;

    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

can you give SortBasedOnMessageId() implementation? Please friend
1

Since Java 8 this can be solved with Integer.compare() function within 1 method:

private JSONArray getSortedMessages(JSONArray array) throws JSONException {
    List<JSONObject> list = new ArrayList<>();
    for (int i = 0; i < array.length(); i++) {
        list.add(array.getJSONObject(i));
    }
    list.sort((a1, a2) -> {
        try {
            return Integer.compare(a1.getInt("messageId"), a2.getInt("messageId"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return 0;
    });
    return new JSONArray(list);
}

1 Comment

Bonus: how to compare a second value when the first ones are equal?
0

Here is a solution:

public static String writeAsSortedJson(Object object) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setNodeFactory(getArrayNodeKeyValueSortingNodeFactory());

    mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
    mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

    String preparedJson = mapper.writeValueAsString(object);
    JsonNode jsonNode = mapper.readTree(preparedJson);

    return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
}

@SuppressWarnings("JavaNCSS")
public static JsonNodeFactory getArrayNodeKeyValueSortingNodeFactory() {
    return new JsonNodeFactory() {
        @Override
        public ObjectNode objectNode() {
            return new ObjectNode(this, new TreeMap<String, JsonNode>());
        }

        @SuppressWarnings("JavaNCSS")
        @Override
        public ArrayNode arrayNode() {
            return new ArrayNode(this, new SortedArrayList<JsonNode>(new Comparator<JsonNode>() {
                @Override
                public int compare(final JsonNode o1, final JsonNode o2) {
                    return compareRecursively(o1, o2);
                }

                private int compareRecursively(final JsonNode o1, final JsonNode o2) {
                    if (o1.isObject() && o2.isObject()) {
                        return compareObjectNodes(o1, o2);
                    } else if (o1.isObject()) {
                        return 1;
                    } else if (o2.isObject()) {
                        return -1;
                    } else if (o1.isArray() && o2.isArray()) {
                        return compareArrayNodes(o1, o2);
                    } else if (o1.isArray()) {
                        return 1;
                    } else if (o2.isArray()) {
                        return -1;
                    }
                    return o1.asText().compareTo(o2.asText());
                }

                private int compareArrayNodes(final JsonNode o1, final JsonNode o2) {
                    List<JsonNode> elements1 = Lists.newArrayList(o1.elements());
                    List<JsonNode> elements2 = Lists.newArrayList(o2.elements());

                    for (int i = 0; i < elements1.size() || i < elements2.size(); i++) {
                        if (i >= elements1.size()) {
                            return -1;
                        } else if (i >= elements2.size()) {
                            return 1;
                        }

                        JsonNode jsonNode1 = elements1.get(i);
                        JsonNode jsonNode2 = elements2.get(i);
                        int compareRecursively = compareRecursively(jsonNode1, jsonNode2);
                        if (compareRecursively != 0) {
                            return compareRecursively;
                        }
                    }

                    return 0;
                }

                @SuppressWarnings("ReturnCountExtended")
                private int compareObjectNodes(JsonNode o1, JsonNode o2) {
                    List<Map.Entry<String, JsonNode>> elements1 = Lists.newArrayList(o1.fields());
                    List<Map.Entry<String, JsonNode>> elements2 = Lists.newArrayList(o2.fields());
                    if (elements1.isEmpty() && elements2.isEmpty()) {
                        return 0;
                    } else if (elements1.isEmpty()) {
                        return -1;
                    } else if (elements2.isEmpty()) {
                        return 1;
                    }

                    for (int i = 0; i < elements1.size() || i < elements2.size(); i++) {
                        if (i >= elements1.size()) {
                            return -1;
                        } else if (i >= elements2.size()) {
                            return 1;
                        }

                        Map.Entry<String, JsonNode> entry1 = elements1.get(i);
                        Map.Entry<String, JsonNode> entry2 = elements2.get(i);
                        int compare = entry1.getKey().compareTo(entry2.getKey());
                        if (compare == 0) {
                            int compareRecursively = compareRecursively(entry1.getValue(), entry2.getValue());
                            if (compareRecursively != 0) {
                                return compareRecursively;
                            }
                        } else {
                            return compare;
                        }
                    }

                    return 0;
                }
            }) { });
        }
    };
}

public static class SortedArrayList<T> implements List<T> {
    private final List<T> delegate = new ArrayList<>();
    private final Comparator<T> comparator;

    public SortedArrayList(Comparator<T> comparator) {
        this.comparator = comparator;
    }

    @Override
    public int size() {
        return delegate.size();
    }

    @Override
    public boolean isEmpty() {
        return delegate.isEmpty();
    }

    @Override
    public boolean contains(final Object o) {
        return delegate.contains(o);
    }

    @NotNull
    @Override
    public Iterator<T> iterator() {
        return delegate.iterator();
    }

    @NotNull
    @Override
    public Object[] toArray() {
        return delegate.toArray();
    }

    @NotNull
    @Override
    public <T1> T1[] toArray(@NotNull final T1[] a) {
        return delegate.toArray(a);
    }

    @Override
    public boolean add(final T t) {
        boolean add = delegate.add(t);
        sort();
        return add;
    }

    @Override
    public void add(final int index, final T element) {
        delegate.add(index, element);
        sort();
    }

    @Override
    public boolean remove(final Object o) {
        boolean remove = delegate.remove(o);
        sort();
        return remove;
    }

    @Override
    public T remove(final int index) {
        T remove = delegate.remove(index);
        sort();
        return remove;
    }

    @Override
    public boolean containsAll(@NotNull final Collection<?> c) {
        return delegate.containsAll(c);
    }

    @Override
    public boolean addAll(@NotNull final Collection<? extends T> c) {
        boolean addAll = delegate.addAll(c);
        sort();
        return addAll;
    }

    @Override
    public boolean addAll(int index, @NotNull Collection<? extends T> c) {
        boolean addAll = delegate.addAll(index, c);
        sort();
        return addAll;
    }

    @Override
    public boolean removeAll(@NotNull final Collection<?> c) {
        boolean removeAll = delegate.removeAll(c);
        sort();
        return removeAll;
    }

    @Override
    public boolean retainAll(@NotNull final Collection<?> c) {
        boolean retainAll = delegate.retainAll(c);
        sort();
        return retainAll;
    }

    @Override
    public void clear() {
        delegate.clear();
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SortedArrayList<?> that = (SortedArrayList<?>) o;
        return Objects.equals(delegate, that.delegate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(delegate);
    }

    @Override
    public T get(final int index) {
        return delegate.get(index);
    }

    @Override
    public T set(final int index, final T element) {
        delegate.set(index, element);
        sort();
        return element;
    }

    @Override
    public int indexOf(final Object o) {
        return delegate.indexOf(o);
    }

    @Override
    public int lastIndexOf(final Object o) {
        return delegate.lastIndexOf(o);
    }

    @NotNull
    @Override
    public ListIterator<T> listIterator() {
        return delegate.listIterator();
    }

    @NotNull
    @Override
    public ListIterator<T> listIterator(final int index) {
        return delegate.listIterator(index);
    }

    @NotNull
    @Override
    public List<T> subList(final int fromIndex, final int toIndex) {
        return delegate.subList(fromIndex, toIndex);
    }

    private void sort() {
        delegate.sort(comparator);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.