Sorting List in Java

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>(){{put("name", "aaa");put("age", 21);}});
        list.add(new HashMap<String, Object>(){{put("name", "ccc");put("age", null);}});
        list.add(new HashMap<String, Object>(){{put("name", "ddd");put("age", null);}});
        list.add(new HashMap<String, Object>(){{put("name", "bbb");put("age", 28);}});
        list.add(new HashMap<String, Object>(){{put("name", "aaa");put("age", 23);}});

        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.

Tags: PHP Java Lambda

Posted on Mon, 04 Nov 2019 11:38:50 -0500 by uday