今天在搬磚的時候遇到這樣一個問題,第三方接口返回的數據格式是json格式的,數據結構是這樣的
[{"name":"a","age":5},{"name":"b","age":3},{"name":"c","age":7}]
我拿到json數據之後解析爲JSONArray,需要根據age這一屬性進行排序,首先想到是的使用JDK1.8的新特性Stream進行排序,但是,問題來了,我JSONArray中裝的每一個對象都是一個Object,並沒有實體對象,換言之,就是Map,list.stream的API中的排序並不能對泛型是Object或者是Map的list進行排序操作,因爲不是實體類,無法get到想要排序的屬性,但是又不想靠循環嵌套來實現排序,畢竟那樣效率有些低下,在困擾了我一段時候後,突然想起,Java自帶的集合操作工具類java.util.Collections中有對list排序的方法,Collections.sort()方法,該方法有兩個構造函數,一個是
/**
* Sorts the specified list into ascending order, according to the
* {@linkplain Comparable natural ordering} of its elements.
* All elements in the list must implement the {@link Comparable}
* interface. Furthermore, all elements in the list must be
* <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)}
* must not throw a {@code ClassCastException} for any elements
* {@code e1} and {@code e2} in the list).
*
* <p>This sort is guaranteed to be <i>stable</i>: equal elements will
* not be reordered as a result of the sort.
*
* <p>The specified list must be modifiable, but need not be resizable.
*
* @implNote
* This implementation defers to the {@link List#sort(Comparator)}
* method using the specified list and a {@code null} comparator.
*
* @param <T> the class of the objects in the list
* @param list the list to be sorted.
* @throws ClassCastException if the list contains elements that are not
* <i>mutually comparable</i> (for example, strings and integers).
* @throws UnsupportedOperationException if the specified list's
* list-iterator does not support the {@code set} operation.
* @throws IllegalArgumentException (optional) if the implementation
* detects that the natural ordering of the list elements is
* found to violate the {@link Comparable} contract
* @see List#sort(Comparator)
*/
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
這個構造函數想必大家都經常用到,就是Collections.sort(list);
.對於String或Integer這些已經實現Comparable接口的類來說,可以直接使用Collections.sort方法傳入list參數來實現默認方式(正序)排序;
更多的我就不在這贅述了,因爲這個函數並不能解決我們當下的問題,我們需要用到另一個構造方法:
/**
* Sorts the specified list according to the order induced by the
* specified comparator. All elements in the list must be <i>mutually
* comparable</i> using the specified comparator (that is,
* {@code c.compare(e1, e2)} must not throw a {@code ClassCastException}
* for any elements {@code e1} and {@code e2} in the list).
*
* <p>This sort is guaranteed to be <i>stable</i>: equal elements will
* not be reordered as a result of the sort.
*
* <p>The specified list must be modifiable, but need not be resizable.
*
* @implNote
* This implementation defers to the {@link List#sort(Comparator)}
* method using the specified list and comparator.
*
* @param <T> the class of the objects in the list
* @param list the list to be sorted.
* @param c the comparator to determine the order of the list. A
* {@code null} value indicates that the elements' <i>natural
* ordering</i> should be used.
* @throws ClassCastException if the list contains elements that are not
* <i>mutually comparable</i> using the specified comparator.
* @throws UnsupportedOperationException if the specified list's
* list-iterator does not support the {@code set} operation.
* @throws IllegalArgumentException (optional) if the comparator is
* found to violate the {@link Comparator} contract
* @see List#sort(Comparator)
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
這個方法並不常用,是Collections的比較器,調用代碼如下:
//重寫比較器
Collections.sort(maps, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
Integer key1 = Integer.valueOf(o1.get("age").toString());
Integer key2 = Integer.valueOf(o2.get("age").toString());
return key1.compareTo(key2);
}
});
對於Map類型或者自定義的實體類型,如果想使用Collections.sort的方式一進行排序,可以通過實現Comparable接口的compareTo方法來進行,不過更多的情況還是針對list的泛型爲Map的情況,因爲JDK1.8的新特性stream的排序操作,更方便快捷。
完整代碼如下:
Map<String, Object> map = new HashMap<>();
map.put("name","a");
map.put("age",5);
Map<String, Object> map1 = new HashMap<>();
map1.put("name","b");
map1.put("age",3);
Map<String, Object> map2 = new HashMap<>();
map2.put("name","c");
map2.put("age",7);
List<Map<String, Object>> maps = new ArrayList<>();
maps.add(map);
maps.add(map1);
maps.add(map2);
String s = JSONObject.toJSONString(maps);
//重寫比較器
Collections.sort(maps, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
Integer key1 = Integer.valueOf(o1.get("age").toString());
Integer key2 = Integer.valueOf(o2.get("age").toString());
return key1.compareTo(key2);
}
});