scene
Bean is defined as follows, with only one age field of type Integer.
@NoArgsConstructor @AllArgsConstructor(staticName = "of") @Data public static class Employee { private Integer age; }
List initializes 5 elements:
List<Employee> list = new ArrayList<>(); list.add(Employee.of(21)); list.add(Employee.of(22)); list.add(Employee.of(25)); list.add(Employee.of(28)); list.add(Employee.of(23));
sort
Sort using the sort method in Collections:
Collections.sort(list, new Comparator<Employee>() { @Override public int compare(Employee o1, Employee o2) { return o1.getAge().compareTo(o2.getAge()); } });
Reverse order:
Collections.reverse(list);
lambda expressions
JDK8 supports lambda expression, which is more concise:
Collections.sort(list, (o1, o2) -> o1.getAge().compareTo(o2.getAge()));
Or use the Comparator interface:
Collections.sort(list, Comparator.comparing(Employee::getAge));
Reverse order:
Collections.sort(list, Comparator.comparing(Employee::getAge).reversed());
stream sorted method
list.stream().sorted(Comparator.comparing(Employee::getAge));
Reverse order:
list.stream().sorted(Comparator.comparing(Employee::getAge).reversed());
sort method of list
list.sort(Comparator.comparing(Employee::getAge));
Reverse order:
list.sort(Comparator.comparing(Employee::getAge).reversed());
null value
Suppose the age field in the list is null:
List<Employee> list = new ArrayList<>(); list.add(Employee.of(21)); list.add(Employee.of(null)); list.add(Employee.of(null)); list.add(Employee.of(28)); list.add(Employee.of(23));
NPE will be reported at this time:
----------------------------- Exception in thread "main" java.lang.NullPointerException at java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469) at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) at java.util.TimSort.sort(TimSort.java:220) at java.util.Arrays.sort(Arrays.java:1512) at java.util.ArrayList.sort(ArrayList.java:1462)
You can use the second parameter of Comparator.comparing:
list.sort(Comparator.comparing(Employee::getAge, Comparator.nullsLast(Comparator.naturalOrder()))); list.sort(Comparator.comparing(Employee::getAge, Comparator.nullsLast(Integer::compareTo))); list.sort(Comparator.comparing(Employee::getAge, Comparator.nullsLast(Comparable::compareTo)));
All of the above 3 can be written. Note that the second parameter uses Comparator.nullsLast to make null last.
Corresponding to this is that Comparator.nullsFirst can be null at the top.
Sort any field
In a recent project, there is a scenario where Map < string, Object > is in the List. You need to support any key sorting of the Map.
The complete code is as follows:
import java.util.*; /** * @author cdfive * @date 2019-05-26 */ public class ListSortDemo2 { public static void main(String[] args) { List<Map<String, Object>> list = new ArrayList<>(); list.add(new HashMap<String, Object>(){}); list.add(new HashMap<String, Object>(){}); list.add(new HashMap<String, Object>(){}); list.add(new HashMap<String, Object>(){}); list.add(new HashMap<String, Object>(){}); printList(list); printLineSep(); sort(list, "age", "asc"); printList(list); } public static void sort(List<Map<String, Object>> list, String sortField, String sortDirection) { if ("desc".equals(sortDirection)) { Comparator<Map<String, Object>> comparator = Comparator.comparing(o -> (Comparable) o.get(sortField), Comparator.nullsFirst(Comparable::compareTo)); list.sort(comparator.reversed()); } else { Comparator<Map<String, Object>> comparator = Comparator.comparing(o -> (Comparable) o.get(sortField), Comparator.nullsLast(Comparable::compareTo)); list.sort(comparator); } } public static void printList(List<?> list) { list.stream().forEach(o -> System.out.print(o)); System.out.println(); } public static void printLineSep() { System.out.println("-----------------------------"); } }
Be careful:
Use Comparator.nullsFirst and comparator.reversed() in reverse order. You need to define the comparator variable separately. If you write directly in one line:
List. Sort (comparator. Comparing (o - >.
Positive sequence uses Comparator.nullsLast.