Sắp xếp đối tượng với Comparator và Comparable

Chào mừng các bạn đã quay trở lại với thachleblog, bài viết hôm nay mình sẽ giới thiệu về vấn đề “sắp xếp đối tượng (object) trong Java”. Câu hỏi này rất căn bản nên thường gặp trong các buổi phỏng vấn Java. Ví dụ có một danh sách sinh viên với các thông tin mã số sinh viên, tên, lớp… làm thế nào để sắp xếp danh sách sinh viên theo mã số sinh viên, tên, lớp? Bạn có thấy quen không? Chúng ta cùng bắt đầu nào.

Giới thiệu

Để sắp xếp đối tượng trong Java chúng ta có hai cách đó là dùng ComparableComparator. Cùng xem code minh họa nhé:

Dùng Comparable

Class Student implement Comparable interface

  1. package sorting.comparable;
  2. public class Student implements Comparable {
  3. private String studentId;
  4. private String name;
  5. private String className;
  6. public Student(String studentId, String name, String className) {
  7. this.studentId = studentId;
  8. this.name = name;
  9. this.className = className;
  10. }
  11. public String getStudentId() {
  12. return studentId;
  13. }
  14. public void setStudentId(String studentId) {
  15. this.studentId = studentId;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public String getClassName() {
  24. return className;
  25. }
  26. public void setClassName(String className) {
  27. this.className = className;
  28. }
  29. // sort by name
  30. @Override
  31. public int compareTo(Student student) {
  32. return this.getName().compareTo(student.getName());
  33. }
  34. }

Class TestComparable minh họa cách dùng Comparable

  1. package sorting.comparable;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. public class TestComparable {
  6. public static void main(String args[]) {
  7. Student student1 = new Student("10520001", "Nguyen Van Hieu", "SE05");
  8. Student student2 = new Student("10520002", "Huynh Van Than", "CS05");
  9. Student student3 = new Student("10520003", "Le Thi Thao", "IS05");
  10. Student student4 = new Student("10520004", "Cao Hoang Vu", "SE05");
  11.  
  12. List students = new ArrayList();
  13. students.add(student1);
  14. students.add(student2);
  15. students.add(student3);
  16. students.add(student4);
  17. // sort by comparable
  18. Collections.sort(students);
  19. for (Student student : students) {
  20. System.out.println("\nStudent name: " + student.getName());
  21. }
  22. }
  23. }

Dùng Comparator

Class Student

  1. package sorting.comparator;
  2. public class Student {
  3. private String studentId;
  4. private String name;
  5. private String className;
  6. public Student(String studentId, String name, String className) {
  7. this.studentId = studentId;
  8. this.name = name;
  9. this.className = className;
  10. }
  11. public String getStudentId() {
  12. return studentId;
  13. }
  14. public void setStudentId(String studentId) {
  15. this.studentId = studentId;
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public String getClassName() {
  24. return className;
  25. }
  26. public void setClassName(String className) {
  27. this.className = className;
  28. }
  29. }

Class NameComparator minh họa cách implement Comparator để sắp xếp Student theo name

  1. package sorting.comparator;
  2. import java.util.Comparator;
  3. public class NameComparator implements Comparator {
  4. @Override
  5. public int compare(Student student1, Student student2) {
  6. return student1.getName().compareTo(student2.getName());
  7. }
  8. }

Class TestComparator minh họa cách dùng Comparator

  1. package sorting.comparator;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. public class TestComparator {
  6. public static void main(String args[]) {
  7. Student student1 = new Student("10520001", "Nguyen Van Hieu", "SE05");
  8. Student student2 = new Student("10520002", "Huynh Van Than", "CS05");
  9. Student student3 = new Student("10520003", "Le Thi Thao", "IS05");
  10. Student student4 = new Student("10520004", "Cao Hoang Vu", "SE05");
  11.  
  12. List students = new ArrayList();
  13. students.add(student1);
  14. students.add(student2);
  15. students.add(student3);
  16. students.add(student4);
  17.  
  18. NameComparator nameComparator = new NameComparator();
  19. Collections.sort(students, nameComparator);
  20. for (Student student : students) {
  21. System.out.println("\nStudent name: " + student.getName());
  22. }
  23. }
  24. }

Kết quả

Cả đều cho kết quả giống nhau

sap xep doi tuong trong java

Khác biệt giữa Comparable và Comparator

Chúng ta cùng xem lại ví dụ minh họa và phân tích điểm khác nhau:

– Implement Comparable cần thay đổi class, cụ thể ở trên là ta thêm đoạn implements Comparable, implement Comparator thì không cần (nếu muốn thì có thể dùng inner class)
– Implement Comparable cần override method comprateTo, implement Comparator cần override method compare
– Có thể sắp xếp đối tượng bằng nhiều option bằng Comparator bằng cách tạo các StudentIdComparator, ClassNameComprator…
– Run Comparable dùng Collections.sort(List), run Comparator dùng Collections.sort(List, Comparator<? super T>)

Vậy khi nào nên dùng Comparable và khi nào thì cần dùng Comparator?

Dùng Comparator khi ta không được phép thay đổi trực tiếp trên class, hoặc cần sắp xếp theo multi option, dùng Comparable khi ta chỉ sắp xếp đối tượng theo 1 option, ta được phép thay đổi trực tiếp trên class và không muốn tạo thêm class mới.
Bản thân mình có lần đã fail phỏng vấn khi gặp câu hỏi này, hy vọng bài viết này giúp các bạn tránh được trường hợp fail giống mình và có khả năng áp dụng ComparatorComparable trong các ứng dụng của mình.

Rất mong nhận được ý kiến từ các bạn.
Xin cảm ơn!

Link tải source code: https://github.com/thachlp/SortingExample

Tham khảo thêm:
http://www.javatpoint.com/Comparator-interface-in-collection-framework
http://java-journal.blogspot.com/2011/01/when-to-use-comparable-and-when-to-use.html