Comparator interface được sử dụng để sắp xếp thứ tự các object của các class do chúng ta tự định nghĩa. Một comparator object có khả năng so sánh hai object khác nhau dựa theo các tiêu chí mà nó tự định nghĩa.
public int compare(Object obj1, Object obj2):
Giả sử chúng ta có một mảng thuộc chứa các Student object có các thuộc tính như rollno, name, address, DOB v.v. và chúng ta cần sắp xếp mảng dựa trên Rollno hoặc name?
Phương pháp 1: Một cách tiếp cận rõ ràng là viết hàm sort () của riêng chúng ta bằng cách sử dụng một trong các thuật toán tiêu chuẩn. Thế nhưng giải pháp này yêu cầu chúng ta phải triển khai lại các thuật toán rất dài dòng.
Phương pháp 2: Sử dụng Comparator interface để định nghĩa cách so sánh giữa 2 Student object với nhau. Sau đó chúng ta có thể sử dụng Collections.sort() được cung cấp sẵn, method này cần nhận vào một Comparator Object được sử dụng trong quá trình nó chạy thuật toán sắp xếp đã được định nghĩa sẵn.
public static <T> void sort(List<T> list, Comparator<? super T> c) {}
Giả sử mình tạo 2 class Sortbyroll và Sortbyname đều implement từ Comparator dùng để so sánh theo roll và name tương ứng
import java.util.*; import java.lang.*; import java.io.*; // A class to represent a student. class Student { int rollno; String name, address; // Constructor public Student(int rollno, String name, String address) { this.rollno = rollno; this.name = name; this.address = address; } // Used to print student details in main() public String toString() { return this.rollno + " " + this.name + " " + this.address; } } class Sortbyroll implements Comparator<Student> { // Used for sorting in ascending order of // roll number public int compare(Student a, Student b) { return a.rollno - b.rollno; } } class Sortbyname implements Comparator<Student> { // Used for sorting in ascending order of // name public int compare(Student a, Student b) { return a.name.compareTo(b.name); } } // Driver class class Main { public static void main (String[] args) { ArrayList<Student> ar = new ArrayList<Student>(); ar.add(new Student(111, "bbbb", "london")); ar.add(new Student(131, "aaaa", "nyc")); ar.add(new Student(121, "cccc", "jaipur")); System.out.println("Unsorted"); for (int i=0; i<ar.size(); i++) System.out.println(ar.get(i)); Collections.sort(ar, new Sortbyroll()); System.out.println("\nSorted by rollno"); for (int i=0; i<ar.size(); i++) System.out.println(ar.get(i)); Collections.sort(ar, new Sortbyname()); System.out.println("\nSorted by name"); for (int i=0; i<ar.size(); i++) System.out.println(ar.get(i)); } }
Output
Unsorted 111 bbbb london 131 aaaa nyc 121 cccc jaipur Sorted by rollno 111 bbbb london 121 cccc jaipur 131 aaaa nyc Sorted by name 131 aaaa nyc 111 bbbb london 121 cccc jaipur
Các bạn có thể thay đổi thứ tự so sánh để đạt được một kết quả sắp xếp giảm dần thay vì tăng dần như ví dụ trên.
Đoạn mã dưới đây cho phép chúng ta sắp xếp giảm dần theo rollno.
class Sortbyroll implements Comparator<Student> { // Used for sorting in ascending order of // roll number public int compare(Student a, Student b) { return b.rollno - a.rollno; } }
Trong ví dụ trên chúng ta đã biết cách triển khai Comparator để sắp xếp các Student theo thứ tự tăng, giảm dần theo rollno, name. Nhưng nếu yêu cầu được thay đổi nho nhỏ rằng sắp xếp các Student theo name, đối với các Student cùng name thì so sánh theo Age.
Từ yêu cầu trên chúng ta có thể thấy rằng việc so sánh giờ đây phải được chia thành 2 cấp, đầu tiên là name sau đó đến age
import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Comparator; class Student { // instance member variables String Name; int Age; // parameterized constructor public Student(String Name, Integer Age) { this.Name = Name; this.Age = Age; } public String getName() { return Name; } public void setName(String Name) { this.Name = Name; } public Integer getAge() { return Age; } public void setAge(Integer Age) { this.Age = Age; } // overriding toString() method @Override public String toString() { return "Customer{" + "Name=" + Name + ", Age=" + Age + '}'; } static class CustomerSortingComparator implements Comparator<Student> { @Override public int compare(Student customer1, Student customer2) { // for comparison int NameCompare = customer1.getName().compareTo(customer2.getName()); int AgeCompare = customer1.getAge().compareTo(customer2.getAge()); // 2-level comparison using if-else block if (NameCompare == 0) { return ((AgeCompare == 0) ? NameCompare : AgeCompare); } else { return NameCompare; } } } public static void main(String[] args) { // create ArrayList to store Student List<Student> al = new ArrayList<>(); // create customer objects using constructor initialization Student obj1 = new Student("Ajay", 27); Student obj2 = new Student("Sneha", 23); Student obj3 = new Student("Simran", 37); Student obj4 = new Student("Ajay", 22); Student obj5 = new Student("Ajay", 29); Student obj6 = new Student("Sneha", 22); // add customer objects to ArrayList al.add(obj1); al.add(obj2); al.add(obj3); al.add(obj4); al.add(obj5); al.add(obj6); // before Sorting arraylist: iterate using Iterator Iterator<Student> custIterator = al.iterator(); System.out.println("Before Sorting:\n"); while (custIterator.hasNext()) { System.out.println(custIterator.next()); } // sorting using Collections.sort(al, comparator); Collections.sort(al, new CustomerSortingComparator()); // after Sorting arraylist: iterate using enhanced for-loop System.out.println("\n\nAfter Sorting:\n"); for (Student customer : al) { System.out.println(customer); } } }
Output
Before Sorting: Customer{Name=Ajay, Age=27} Customer{Name=Sneha, Age=23} Customer{Name=Simran, Age=37} Customer{Name=Ajay, Age=22} Customer{Name=Ajay, Age=29} Customer{Name=Sneha, Age=22} After Sorting: Customer{Name=Ajay, Age=22} Customer{Name=Ajay, Age=27} Customer{Name=Ajay, Age=29} Customer{Name=Simran, Age=37} Customer{Name=Sneha, Age=22} Customer{Name=Sneha, Age=23}
Nguồn tham khảo