Sắp xếp ArrayList chứa các phần tử null

Ở các bài trước, chắc ta đã tìm hiểu về rất nhiều cách sắp xếp ArrayList như Sắp xếp tăng, giảm, Sắp xếp theo cấp, các thuộc tính khác nhau.

Vào ngày đẹp trời mình nhận được một con bug Nullpointer từ team test. Loay hoay một hồi debug đến đoạn sắp xếp mảng. Nhìn tổng thể thì mình không tài nào đoán được nguyên nhân dẫn đến lỗi. 

Bình tĩnh, xin data của team test, mới vỡ oà trong Arraylist có một phần tử null. Ok, cùng tìm cách giải quyết thôi.

Trước hết chúng ta xem đoạn code lỗi 

// File Main.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        List<Integer> arr = new ArrayList<>();
        arr.add(9);
        arr.add(4);
        arr.add(-1);
        arr.add(7);
        arr.add(null);
        Collections.sort(arr, Comparator.comparingInt(o -> o));
    }
}

Output:

Exception in thread “main” java.lang.NullPointerException
at Main.lambda$main$0(Main.java:14)

Sau khi đã biết được vấn đề rồi, mình nhanh trí nghĩ ra cách khá hay là custom comparator

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        List<Integer> arr = new ArrayList<>();
        arr.add(9);
        arr.add(4);
        arr.add(-1);
        arr.add(7);
        arr.add(null);
        Collections.sort(arr, (o1, o2) -> {
            if (o1 == null) {
                return -1;

            }
            else if (o2 == null) {
                return 1;
            } else {
                return o1 - o2;
            }
        });
        arr.forEach(e -> System.out.print(e + " "));
    }
}

Output: null -1 4 7 9

Ở trên ý mình là nếu có phần tử null thì đẩy nó lên đầu tiên của ArrayList. 

Um, cách trên thì mình nghĩ code đã rất ngon, mình chỉ cần kiểm tra null là không xử lý gì thôi.

Thế nhưng suy nghĩ lại thì suy cho cùng ArrayList chứa một phần tử null là chuyện rất thường hay xảy ra, thì chắc hẳn team java họ đã biết trước chuyện đó và xử lý giúp chúng ta rồi.

Search một xíu nào, chúng ta có 2 từ khoá giải quyết cho trường hợp của trên:

  • nullsFirst

  • nullsLast

nullsFirst

Đặt các phần tử null lên đầu ArrayList sau khi hoàn tất quá trình sắp xếp

Syntax:

public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator);

Như trên hàm nullsFirst() trả về Comparator nên chúng ta có thể tuỳ ý sử dụng với Collections.sort() hoặc ArrayList.sort().

// File Main.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        List<Integer> arr = new ArrayList<>();
        arr.add(9);
        arr.add(4);
        arr.add(-1);
        arr.add(7);
        arr.add(null);
        Collections.sort(arr, Comparator.nullsFirst(Comparator.comparingInt(o -> o)));
        
        //arr.sort(Comparator.nullsFirst(Comparator.comparingInt(o -> o)));
        
        arr.forEach(e -> System.out.print(e + " "));
    }
}

Output: null -1 4 7 9

nullsLast

Chuyển các phần tử null xuống cái ArrayList sau khi hoàn tất quá trình sắp xếp.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String args[]) {
        List<Integer> arr = new ArrayList<>();
        arr.add(9);
        arr.add(4);
        arr.add(-1);
        arr.add(7);
        arr.add(null);
        Collections.sort(arr, Comparator.nullsLast(Comparator.comparingInt(o -> o)));

        //arr.sort(Comparator.nullsLast(Comparator.comparingInt(o -> o)));

        arr.forEach(e -> System.out.print(e + " "));
    }
}

Output: -1 4 7 9 null 

Note:

nullsFirstnullsLast chỉ có tác dụng đẩy các phần tử null lên đầu hoặc cuối ArrayList, mà vẫn giữ nguyên kết quả sắp xếp trong biểu thức. Ví dụ, mình sắp xếp tăng dần, trong cả 2 ví dụ thứ tự tăng dần vẫn không đổi chỉ có vị trí của các phần tử bị null được di chuyển.

‹Previous Next›

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x