Java 8 – 如何对具有空值的列表和数组进行排序?

Java 8 - 如何对具有空值的列表和数组进行排序? - BenchResources.Net

在本文中,我们将了解如何对存在空值的对象列表数组进行排序

通常,对其中包含一个或多个空值的任何列表/数组进行排序,会导致在将空值与其他值进行比较时抛出NullPointerException

要解决此NullPointerException,我们必须在Comparator逻辑内处理 null 值在 Java 8 方法之前),或者使用Java 8中引入的Comparator接口的静态方法nullsFirst()nullsLast()

 

对具有空值的列表和数组进行排序:

让我们在不同的子主题下讨论这个主题,如下所示,

  • 对具有空值的列表进行排序时抛出NullPointerException
  • Java 8之前–排序手动处理空值
  • Java 8 –具有值的整数排序列表
  • Java 8 –具有值的字符串排序列表
  • Java 8 –具有空值的Customer对象排序列表
  • Java 8 –过滤值并对字符串元素进行排序
  • 收藏。排序()方法
  • 数组。排序()方法

 

 

1. 对空值列表进行排序时抛出 NullPointerException :

  • 在这里,我们尝试对包含值的字符串元素列表进行排序
  • 在下面的示例中,在比较null值时Comparator抛出NullPointerException
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class SortingNullValuesThrowsNPE {
 
    public static void main(String[] args) {
 
        // 1. string list
        List<String> names = Arrays.asList(
                null,
                "Kimi",
                "Michael",
                null,
                "Alonso",
                "Narain",
                null
                );
 
        // 2.1 Sorting list with null values
        Collections.sort(names, Comparator.naturalOrder());
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.compareTo(String.java:1155)
    at java.lang.String.compareTo(String.java:111)
    at java.util.Comparators$NaturalOrderComparator.compare(Comparators.java:52)
    at java.util.Comparators$NaturalOrderComparator.compare(Comparators.java:47)
    at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
    at java.util.TimSort.sort(TimSort.java:220)
    at java.util.Arrays.sort(Arrays.java:1438)
    at java.util.Arrays$ArrayList.sort(Arrays.java:3895)
    at java.util.Collections.sort(Collections.java:175)
    at net.bench.resources.stream.sorting.nullvalues.SortingNullValuesThrowsNPE
.main(SortingNullValuesThrowsNPE.java:24)

 

2. Java 8之前 – 排序时手动处理空值:

  • 为了摆脱我们在上一个示例中遇到的NullPointerException,我们将在比较器逻辑中手动处理空值,方法是将它们推到最后
  • 但我们仍然必须通过在比较器内部编写/编码/开发逻辑来将值推到第一个/最后一个位置,从而使我们的双手变得肮脏
  • 一种更优雅的方法是使用Java 8 的 Comparator接口中引入的静态方法nullsFirstnullsLast),我们将在下面的示例中看到。3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class SortingBeforeJava8Approach {
 
    public static void main(String[] args) {
 
        // 1. string list
        List<String> names = Arrays.asList(
                null,
                "Kimi",
                "Michael",
                null,
                "Alonso",
                "Narain",
                null
                );
 
        // 1.1 printing original names list
        System.out.println("Unsorted names list with NULL values :- \n");
        names.forEach(System.out::println);
 
 
        // 2.
        System.out.println("\n\nCollections.sort() with NULL values Last:- \n");
 
        // 2.1 Sorting using Collections.sort() with null values last
        Collections.sort(names, new Comparator<String>() {
 
            @Override
            public int compare(String str1, String str2) {
                if(null == str1) {
                    return null == str2 ? 0 : 1;
                }
                else if(null == str2) {
                    return -1;
                }
                return str1.compareTo(str2);
            }
        });
 
        // 2.2 print to console
        names.forEach(System.out::println);
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Unsorted names list with NULL values :-
 
null
Kimi
Michael
null
Alonso
Narain
null
 
 
Collections.sort() with NULL values Last:-
 
Alonso
Kimi
Michael
Narain
null
null
null

3. Java 8 – 具有空值的整数排序列表:

  • 在这里,我们使用Comparator接口的静态方法nullsFirst()nullsLast()对包含null值的整数列表进行排序
  • 比较器。nullsFirst() – 该比较器有助于将null值推到第一个/起始位置
  • 比较器。nullsLast() – 该比较器有助于将null值推到最后/结束位置
  • 其余非空整数值将根据作为参数传递给静态方法的比较器升序/降序排序,即;nullsFirst()nullsLast()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
public class IntegerSortingUsingJava8 {
 
    public static void main(String[] args) {
 
        // integer list
        List<Integer> names = Arrays.asList(
                97, null, 63, 19, null, 86, 23, null
                );
 
        // printing original number list
        System.out.println("Unsorted number list with NULL values :- \n");
        names.forEach(System.out::println);
 
 
        // stream sorting with null values first
        System.out.println("\n\nSorted number list with NULL values First:- \n");
        names
        .stream()
        .sorted(Comparator.nullsFirst(Comparator.naturalOrder()))
        .forEach(System.out::println);
 
 
        // stream sorting with null values last
        System.out.println("\n\nSorted number list with NULL values Last:- \n");
        names
        .stream()
        .sorted(Comparator.nullsLast(Comparator.naturalOrder()))
        .forEach(System.out::println);
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Unsorted number list with NULL values :-
 
97
null
63
19
null
86
23
null
 
 
Sorted number list with NULL values First:-
 
null
null
null
19
23
63
86
97
 
 
Sorted number list with NULL values Last:-
 
19
23
63
86
97
null
null
null

 

4. Java 8 – 具有空值的字符串排序列表:

  • 在这里,我们使用Comparator接口的静态方法nullsFirst()nullsLast()对包含null值的 String 元素列表进行排序
  • 比较器。nullsFirst() – 这个比较器有助于将null值推到第一个/起始位置,并且为了对其余非 null String 元素进行排序,我们可以传递Comparator.naturalOrder()Comparator.reverseOrder()自然/反向顺序获得结果分别
  • 比较器。nullsLast() – 此比较器有助于将值推到最后/结束位置,并且类似地可以对其余非空项目进行排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
public class StringSortingUsingJava8 {
 
    public static void main(String[] args) {
 
        // string list
        List<String> names = Arrays.asList(
                null,
                "Kimi",
                "Michael",
                null,
                "Alonso",
                "Narain",
                null
                );
 
        // printing original names list
        System.out.println("Unsorted names list with NULL values :- \n");
        names.forEach(System.out::println);
 
 
        // stream sorting with null values first
        System.out.println("\n\nSorted names list with NULL values First:- \n");
        names
        .stream()
        .sorted(Comparator.nullsFirst(Comparator.naturalOrder()))
        .forEach(System.out::println);
 
 
        // stream sorting with null values last
        System.out.println("\n\nSorted names list with NULL values Last:- \n");
        names
        .stream()
        .sorted(Comparator.nullsLast(Comparator.naturalOrder()))
        .forEach(System.out::println);
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Unsorted names list with NULL values :-
 
null
Kimi
Michael
null
Alonso
Narain
null
 
 
Sorted names list with NULL values First:-
 
null
null
null
Alonso
Kimi
Michael
Narain
 
 
Sorted names list with NULL values Last:-
 
Alonso
Kimi
Michael
Narain
null
null
null

 

5. Java 8 – 对具有空值的 Customer 对象进行排序:

  • 我们将根据名称字母顺序对包含空值的 Customer 对象列表进行排序
  • 比较器。nullsFirst() – 这个比较器有助于将null值推到第一个/起始位置,并根据名称对其余非空 Customer 对象进行排序,我们可以将Lambda 表达式方法引用传递 给Streamsorted()方法
  • 比较器。nullsLast() – 此比较器有助于将null值推到最后/结束位置,并且类似于根据名称对其余非空 Customer 对象进行排序,我们可以将Lambda 表达式方法引用传递Streamsorted()方法

Customer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package net.bench.resources.stream.sorting.nullvalues;
 
public class Customer {
 
    // member variables
    String custName;
    String custCity;
    Integer custAge;
 
    // 3-arg parameterized constructor
 
    // getters & setters
 
    // toString() method
}

CustomerSortingUsingJava8.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
 
public class CustomerSortingUsingJava8 {
 
    // customer list
    private static List<Customer> getUnSortedCustomers() {
 
        return Arrays.asList(
                null,
                new Customer("Sneha", "Pune"73),
                new Customer("Simran", "Bangalore", 37),
                new Customer("Nayanthara", "Hyderabad", 52),
                new Customer("Shalini", "Chennai", 70),
                null,
                new Customer("Abirami", "Bangalore", 48),
                new Customer("Trisha", "Mangalore", 45),
                null
                );
    }
 
    public static void main(String[] args) {
 
        // get customer list
        List<Customer> unsortedCustomerList = getUnSortedCustomers();
 
        System.out.println("Before Sorting: Customer list :- \n");
        unsortedCustomerList.stream().forEach(System.out::println);
 
 
        System.out.println("\n\nSorted Customer list on Name"
                + " with NULL values First :- \n");
 
        // inline - sorting on multiple fields
        List<Customer> sortedCustomerListWithNullFirst = unsortedCustomerList
                .stream()
                .sorted(Comparator.nullsFirst(Comparator
                        .comparing(Customer::getCustName)))
                .collect(Collectors.toList()); // collect sorted customers to new list
 
        // print new list to console using forEach()
        sortedCustomerListWithNullFirst.stream().forEach(System.out::println);
 
 
        System.out.println("\n\nSorted Customer list on Name"
                + " with NULL values Last :- \n");
 
        // inline - sorting on multiple fields
        List<Customer> sortedCustomerListWithNullLast = unsortedCustomerList
                .stream()
                .sorted(Comparator.nullsLast(Comparator
                        .comparing(Customer::getCustName)))
                .collect(Collectors.toList()); // collect sorted customers to new list
 
        // print new list to console using forEach()
        sortedCustomerListWithNullLast.stream().forEach(System.out::println);
    }
}

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Before Sorting: Customer list :-
 
null
Customer [custName=Sneha, custCity=Pune, custAge=73]
Customer [custName=Simran, custCity=Bangalore, custAge=37]
Customer [custName=Nayanthara, custCity=Hyderabad, custAge=52]
Customer [custName=Shalini, custCity=Chennai, custAge=70]
null
Customer [custName=Abirami, custCity=Bangalore, custAge=48]
Customer [custName=Trisha, custCity=Mangalore, custAge=45]
null
 
 
Sorted Customer list on Name with NULL values First :-
 
null
null
null
Customer [custName=Abirami, custCity=Bangalore, custAge=48]
Customer [custName=Nayanthara, custCity=Hyderabad, custAge=52]
Customer [custName=Shalini, custCity=Chennai, custAge=70]
Customer [custName=Simran, custCity=Bangalore, custAge=37]
Customer [custName=Sneha, custCity=Pune, custAge=73]
Customer [custName=Trisha, custCity=Mangalore, custAge=45]
 
 
Sorted Customer list on Name with NULL values Last :-
 
Customer [custName=Abirami, custCity=Bangalore, custAge=48]
Customer [custName=Nayanthara, custCity=Hyderabad, custAge=52]
Customer [custName=Shalini, custCity=Chennai, custAge=70]
Customer [custName=Simran, custCity=Bangalore, custAge=37]
Customer [custName=Sneha, custCity=Pune, custAge=73]
Customer [custName=Trisha, custCity=Mangalore, custAge=45]
null
null
null

 

6. Java 8 – 过滤掉空值并对字符串元素进行排序:

  • 首先使用Streamfilter()方法从字符串列表中删除空值
  • 列表中过滤掉空值后,我们可以通过将Comparator传递给StreamSorted()方法来对列表中存在的其余String 元素进行排序
  • 使用Comparator.naturalOrder()方法进行升序(或字母顺序)
  • 使用Comparator.reverseOrder()方法按反向字母顺序对 String 元素进行排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
public class FilterAndThenSortUsingJava8 {
 
    public static void main(String[] args) {
 
        // string list
        List<String> names = Arrays.asList(
                null,
                "Kimi",
                "Michael",
                null,
                "Alonso",
                "Narain",
                null
                );
 
        // printing original names list
        System.out.println("Unsorted names list with NULL values :- \n");
        names.forEach(System.out::println);
 
        // remove null values using filter() and then sorted()
        System.out.println("\n\nSorted names list "
                + "after filtering out NULL values :- \n");
 
        names // original data source
        .stream() // sequential stream
        .filter(str -> null != str) // filter()
        .sorted(Comparator.naturalOrder()) //sorted()
        .forEach(System.out::println); // forEach()
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Unsorted names list with NULL values :-
 
null
Kimi
Michael
null
Alonso
Narain
null
 
 
Sorted names list after filtering out NULL values :-
 
Alonso
Kimi
Michael
Narain

 

7. Collections.sort()方法:

  • 该方法需要2 个参数,即;第一个是要排序的实际列表第二比较器
  • 由于我们尝试对存在null 值的列表进行排序,因此我们可以使用nullsFirst()nullsLast()静态方法分别将null值推送到开始/结束位置
  • 此外,我们必须将另一个Comparator作为参数传递给nullFirst/nullsLast静态方法,以便按升序/降序对其余非空值进行排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class Java8SortingUsingCollectionsSortMethod {
 
    public static void main(String[] args) {
 
        // 1. string list
        List<String> names = Arrays.asList(
                null,
                "Kimi",
                "Michael",
                null,
                "Alonso",
                "Narain",
                null
                );
 
        // 1.1 printing original names list
        System.out.println("Unsorted names list with NULL values :- \n");
        names.forEach(System.out::println);
 
 
        // 2.1 Sorting using Collections.sort() with null values first
        Collections.sort(names, Comparator
                .nullsFirst(Comparator.naturalOrder()));
 
        // 2.2 nullsFirst -> print to console
        System.out.println("\n\nCollections.sort() with NULL values First:- \n");
        names.forEach(System.out::println);
 
 
        // 3.1 Sorting using Collections.sort() with null values first
        Collections.sort(names, Comparator
                .nullsLast(Comparator.naturalOrder()));
 
        // 3.2 nullsLast -> print to console
        System.out.println("\n\nCollections.sort() with NULL values Last:- \n");
        names.forEach(System.out::println);
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Unsorted names list with NULL values :-
 
null
Kimi
Michael
null
Alonso
Narain
null
 
 
Collections.sort() with NULL values First:-
 
null
null
null
Alonso
Kimi
Michael
Narain
 
 
Collections.sort() with NULL values Last:-
 
Alonso
Kimi
Michael
Narain
null
null
null

 

8.Arrays.sort()方法:

  • 这也与Collections.sort()方法非常相似,除了一个参数数组
  • 该方法需要2 个参数,即;第一个是要排序的实际数组第二比较器
  • 由于我们尝试对存在null 值的数组进行排序,因此我们可以使用nullsFirst()nullsLast()静态方法分别将null值推送到起始/最后位置
  • 此外,我们必须将另一个Comparator作为参数传递给nullFirst/nullsLast方法,以便按升序/降序对其余非空值进行排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package net.bench.resources.stream.sorting.nullvalues;
 
import java.util.Arrays;
import java.util.Comparator;
 
public class Java8SortingUsingArraysSortMethod {
 
    public static void main(String[] args) {
 
        // 1. string list
        String[] names = {
                null,
                "Kimi",
                "Michael",
                null,
                "Alonso",
                "Narain",
                null
        };
 
        // 1.1 printing original names list
        System.out.println("Unsorted names list with NULL values :- \n");
        System.out.println(Arrays.toString(names));
 
 
        // 2.1 Sorting using Arrays.sort() with null values first
        Arrays.sort(names, Comparator.nullsFirst(Comparator.naturalOrder()));
 
        // 2.2 nullsFirst -> print to console
        System.out.println("\n\nArrays.sort() with NULL values First:- \n");
        System.out.println(Arrays.toString(names));
 
 
        // 3.1 Sorting using Arrays.sort() with null values first
        Arrays.sort(names, Comparator.nullsLast(Comparator.naturalOrder()));
 
        // 3.2 nullsLast -> print to console
        System.out.println("\n\nArrays.sort() with NULL values Last:- \n");
        System.out.println(Arrays.toString(names));
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
Unsorted names list with NULL values :-
 
[null, Kimi, Michael, null, Alonso, Narain, null]
 
 
Arrays.sort() with NULL values First:-
 
[null, null, null, Alonso, Kimi, Michael, Narain]
 
 
Arrays.sort() with NULL values Last:-
 
[Alonso, Kimi, Michael, Narain, null, null, null]

 

相关文章:

 

参考:

posted @ 2023-12-23 20:42  CharyGao  阅读(538)  评论(0编辑  收藏  举报