Reputation: 1201
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
Upvotes: 3
Views: 19699
Reputation: 325
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);
}
}
Upvotes: 0
Reputation: 119
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);
}
Upvotes: 1
Reputation: 1201
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;
}
}
Upvotes: 10