Java 8 sorting

Today, I share 10 postures for sorting in Java 8, which is actually to string together knowledge points such as Lambda, Stream, and method references in Java 8

traditional sort

Now there is a List collection:

public static List<User> LIST = new ArrayList() {
    
    
    {
    
    
        add(new User("Lisa", 23));
        add(new User("Tom", 11));
        add(new User("John", 16));
        add(new User("Jessie", 26));
        add(new User("Tony", 26));
        add(new User("Messy", 26));
        add(new User("Bob", 19));
        add(new User("Yoga", 65));
    }
};

Sorting before jdk8:

/**
 * jdk8 之前的排序
 */
private static void sortPreJdk8() {
    
    
    System.out.println("=====jdk8 之前的排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    Collections.sort(list, new Comparator<User>() {
    
    
        @Override
        public int compare(User u1, User u2) {
    
    
            return u1.getAge().compareTo(u2.getAge());
        }
    });
 
    for (User user : list) {
    
    
        System.out.println(user);
    }
    System.out.println();
}

Sorting in Java 8

1. Lambda sorting (with parameter type) The List interface in Java 8 adds a sort default method:
insert image description here
receiving the Comparator interface parameter, which is modified as a functional interface in Java 8:
insert image description here
then we can change the Comparator interface parameter to In the form of Lambda expressions, anonymous inner classes are eliminated with Lambda expressions, making the code more concise.

An example of use is as follows:

/**
 * jdk8 lambda 排序,带参数类型
 */
private static void sortWithJdk8Lambda1() {
    
    
    System.out.println("=====jdk8 lambda 排序,带参数类型=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort((User u1, User u2) -> u1.getAge().compareTo(u2.getAge()));
 
    list.forEach(System.out::println);
    System.out.println();
}

2. Lambda sorting (without parameter types)
Lambda expressions can be sorted without parameter types, as shown in the following example:

/**
 * jdk8 lambda 排序,不带参数类型
 */
private static void sortWithJdk8Lambda2() {
    
    
    System.out.println("=====jdk8 lambda 排序,不带参数类型=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort((u1, u2) -> u1.getAge().compareTo(u2.getAge()));
 
    list.forEach(System.out::println);
    System.out.println();
}

The u1 and u2 in the code are not decorated with the User class, it will be automatically inferred as the User type, because the collection itself is a User generic type.

3. Static method reference sorting
In addition to Lambda expressions, static method references of classes can also be used:

/**
 * jdk8 静态方法引用排序
 */
private static void sortWithJdk8StaticMethodRef() {
    
    
    System.out.println("=====jdk8 静态方法引用排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort(User::compareAge);
 
    list.forEach(System.out::println);
    System.out.println();
}

Is the code more concise after using method references?

4. Instance method reference sorting
Not only can use the static method of the class, but also can use the common method reference of the instance method of the class:

/**
 * jdk8 实例方法引用排序
 */
private static void sortWithJdk8InstanceMethodRef() {
    
    
    System.out.println("=====jdk8 实例方法引用排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort(User.getInstance()::compare);
 
    list.forEach(System.out::println);
    System.out.println();
}

This getInstance here is actually a singleton, but it has nothing to do with singletons, any class instance is fine.

In addition, I have also organized these knowledge points into small programs, which are often tested in interviews. You can use the Java interview library small program to brush up the questions online.

5. Comparator tool class sorting (ascending order)
Java 8 adds a comparing method in the Comparator interface:
insert image description here
this tool method needs to provide a functional interface parameter, that is, which field to compare, and finally returns the Comparator interface instance.

An example of use is as follows:

/**
 * jdk8 升序排序,Comparator 提供的静态方法
 */
private static void sortWithJdk8ComparatorAsc() {
    
    
    System.out.println("=====jdk8 升序排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort(Comparator.comparing(User::getAge));
    
//  list.sort(Comparator.comparing((user) -> user.getAge()));
 
    list.forEach(System.out::println);
    System.out.println();
}

Since it is a functional interface, Lambda and method references can be used as parameters.

6. Comparator tool class sorting (descending order)
can also use the Comparator.reversed/ reversedOrder method for descending order:

/**
 * jdk8 Comparator 工具类排序(降序)
 */
private static void sortWithJdk8ComparatorDesc() {
    
    
    System.out.println("=====jdk8 降序降序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort(Comparator.comparing(User::getAge).reversed());
 
    list.forEach(System.out::println);
    System.out.println();
}

7. Combination sorting
If you want to sort by user's age first, and then sort by name if they are the same age, you can use the thenComparing default method in the Comparator interface:

private static void sortGroupWithJdk8() {
    
    
    System.out.println("=====jdk8 组合排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list.sort(Comparator.comparing(User::getAge).thenComparing(User::getName));
 
    list.forEach(System.out::println);
    System.out.println();
}

Output:
insert image description here
Notice that people with age 26 are sorted by name in natural order again.

8. Stream sorting
You can also convert the List collection into a Stream, and then use its sorted method:
insert image description here
The sorted method also receives Comparator interface parameters, so we can also use Lambda, method references, and tool methods provided by the Comparator interface itself to call it:

/**
 * jdk8 Stream 排序
 */
private static void sortWithJdk8Stream() {
    
    
    System.out.println("=====jdk8 Stream 排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list = list.stream().sorted(User::compareAge).collect(Collectors.toList());
 
//  list = list.stream().sorted((u1, u2) -> u1.getAge().compareTo(u2.getAge())).collect(Collectors.toList());
 
//  list = list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
    
 
    list.forEach(System.out::println);
    System.out.println();
}

Therefore, using Stream can also expand multiple sorting methods, see the comment section, and I will not expand here. In addition, I have written a topic on the Stream series before, so I won’t expand it here. If you don’t understand, pay attention to the Java technology stack of the official account, and then read it in the Java tutorial menu of the official account.

9. Parallel Stream sorting
If there is Stream sorting, then parallel Stream (parallelStream) sorting:

/**
 * jdk8 并行 Stream 排序
 */
private static void sortWithJdk8parallelStream() {
    
    
    System.out.println("=====jdk8 Stream 排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    list = list.parallelStream().sorted(User::compareAge).collect(Collectors.toList());
 
    list.forEach(System.out::println);
    System.out.println();
}

10. Collections sorting
Since the Comparator interface is defined as a functional interface in Java 8, our traditional Collections tool class can be changed, and we can also use Lambda, method references, and tool methods provided by the Comparator interface itself. transfer:

/**
 * jdk8 Collections 排序
 */
private static void sortWithCollections() {
    
    
    System.out.println("=====jdk8 Collections 排序=====");
    List<User> list = new ArrayList<>(LIST);
 
    Collections.sort(list, User::compareAge);
    
//  Collections.sort(list, (u1, u2) -> u1.getAge().compareTo(u2.getAge()));
//  Collections.sort(list, Comparator.comparing(User::getAge));    
 
    list.forEach(System.out::println);
    System.out.println();
}

Summarize

This article lists 10 sorting methods in Java 8, which are actually 10 cases, and more can be expanded, just for your reference. Generally speaking, they can be divided into 3 categories:

The sort method in the List interface

The sorted method in the Stream interface

Collections.sort utility class method

All three methods can receive the Comparator interface as a parameter, and the Comparator interface is defined as a functional interface in Java 8, so we can pass in different parameter forms such as Lambda expressions, method references, and Comparator's own tool classes. It can be said to be too beautiful.

How do these methods perform?

I wrote a small example, a collection of 10,000 data, using static method references for testing:

long start = System.currentTimeMillis();
List<User> list1 = new ArrayList<>(list);
list1.sort(User::compareAge);
System.out.println("List.sort: " + (System.currentTimeMillis() - start));
 
start = System.currentTimeMillis();
List<User> list2 = new ArrayList<>(list);
Collections.sort(list2, User::compareAge);
System.out.println("Collections.sort: " + (System.currentTimeMillis() - start));
 
start = System.currentTimeMillis();
List<User> list3 = new ArrayList<>(list);
list3.stream().sorted(User::compareAge).collect(Collectors.toList());
System.out.println("Stream.sorted: " + (System.currentTimeMillis() - start));

Output result:

List.sort: 18 Collections.sort: 18 Stream.sorted: 48
stream is slightly slower, because there are two more conversion processes, but if the amount of data is not particularly large, such as a collection of 1000 data, these three have almost the same performance , the sorting is basically completed within 1 millisecond, and the sorting of ordinary small data can be used with eyes closed.

Guess you like

Origin blog.csdn.net/m0_51406695/article/details/129398579