Comparable & Comparator & Collections.sort trong Java
Comparable và Comparator là hai giao diện trong Java được sử dụng để so sánh các đối tượng để xác định thứ tự của chúng. Mục tiêu chung của cả hai là cho phép bạn sắp xếp các đối tượng dựa trên một số tiêu chí. Tuy nhiên, chúng có cách thức và mục đích sử dụng khác nhau
1. Comparable
- Comparable là một giao diện trong Java được áp dụng trực tiếp cho một lớp cụ thể. Điều này có nghĩa là lớp đó "tự nói" cách nó sẽ được so sánh với các đối tượng khác.
- Khi bạn triển khai Comparable trong lớp của mình, bạn phải cung cấp một phương thức compareTo để xác định cách so sánh đối tượng hiện tại với một đối tượng khác. Phương thức này trả về một số nguyên âm, 0 hoặc dương tương ứng với kết quả của so sánh.
- Comparable thường được sử dụng khi bạn muốn xác định một cách mặc định cho việc so sánh các đối tượng trong lớp của bạn và không cần sử dụng nhiều cách so sánh khác nhau.
Ví dụ:
Giả sử bạn có một lớp 'Product' đại diện cho thông tin về các sản phẩm và bạn muốn sắp xếp các sản phẩm dựa trên giá tiền của chúng.
Bạn có thể triển khai 'Comparable' trong lớp 'Product' để xác định cách so sánh dựa trên giá:
Trong ví dụ này, phương thức compareTo
được triển khai để so sánh hai sản phẩm dựa trên giá tiền của chúng. Khi bạn sử dụng Collections.sort
hoặc Arrays.sort
trên một danh sách hoặc mảng của các đối tượng Product
, phương thức compareTo
sẽ được gọi để thực hiện việc sắp xếp.
2. Comparator
- Comparator là một giao diện trong Java được sử dụng để xác định một cách tường minh cách so sánh giữa các đối tượng không phải là của bạn.
- Bạn có thể triển khai nhiều lớp Comparator khác nhau để sắp xếp các đối tượng dựa trên các tiêu chí khác nhau. Điều này cho phép bạn thay đổi cách so sánh mà không cần thay đổi lớp đối tượng.
- Comparator thường được sử dụng khi bạn cần thực hiện nhiều cách so sánh khác nhau cho cùng một lớp đối tượng hoặc khi bạn không thể sửa đổi lớp đối tượng để triển khai Comparable.
Ví dụ:
Khi bạn cần sắp xếp danh sách các sản phẩm theo tên, bạn có thể sử dụng NameComparator
như sau:
Trong ví dụ này, bạn sử dụng Comparator
để xác định cách so sánh dựa trên tên mà không cần thay đổi lớp Product
Ví dụ Sử dụng Comparator bằng cách tạo lớp nặc danh (Anonymous Class)
Trong ví dụ này, chúng ta sử dụng Arrays.sort để sắp xếp mảng names. Để chỉ định cách so sánh, chúng ta tạo một lớp nặc danh (anonymous class) implements Comparator< String > . Lớp này có một phương thức compare để so sánh độ dài của hai chuỗi. Sau đó, chúng ta truyền một đối tượng của lớp nặc danh này như là tham số cho phương thức sort.
Khi chạy chương trình, bạn sẽ thấy mảng names được sắp xếp theo độ dài của chuỗi: [Bob, Alice, David, Charlie, Edward]
Bạn cũng có thể sử dụng lambda expression trong Java 8, để việc sử dụng Comparator trở nên ngắn gọn và dễ đọc hơn
Trong ví dụ này, chúng ta sử dụng Arrays.sort cũng như trước, nhưng thay vì tạo một lớp nặc danh, chúng ta sử dụng lambda expression để triển khai Comparator ngay tại chỗ. Lambda expression (s1, s2) -> Integer.compare(s1.length(), s2.length()) thực hiện chính xác công việc so sánh độ dài của hai chuỗi giống như lớp nặc danh trước đó.
Kết quả sẽ giống như trước: [Bob, Alice, David, Charlie, Edward]
3. Khi nào nên sử dụng Comparable và Comparator:
- Sử dụng Comparable khi bạn muốn xác định một cách mặc định để so sánh các đối tượng trong cùng một lớp và không cần nhiều cách so sánh khác nhau.
- Sử dụng Comparator khi bạn cần xác định một hoặc nhiều cách so sánh khác nhau cho các đối tượng không phải là của bạn hoặc khi bạn muốn duy trì tính tách biệt giữa logic so sánh và lớp đối tượng.
4. Collections.sort cách sử dụng nó
Collections.sort là một phương thức static của lớp Collections trong Java dùng để sắp xếp các phần tử của collection theo một thứ tự cụ thể. Dưới đây là cách bạn có thể sử dụng Collections.sort:
1. Sắp xếp danh sách sử dụng Comparable:
- Khi đối tượng trong danh sách đã triển khai giao diện Comparable, bạn có thể sắp xếp danh sách một cách dễ dàng bằng cách gọi Collections.sort(list):
2. Sắp xếp danh sách sử dụng Comparator
- Khi bạn cần sắp xếp danh sách dựa trên một cách so sánh khác với cách mà các đối tượng đã triển khai Comparable, bạn có thể sử dụng Comparator:
- Lưu ý rằng trong ví dụ thứ hai, NameComparator là một lớp triển khai Comparator, và bạn truyền một đối tượng Comparator vào phương thức Collections.sort
3. Ví dụ sắp xếp một danh sách String
- Lưu ý rằng trong trường hợp sắp xếp chuỗi, String đã triển khai giao diện Comparable sẵn có, vì vậy bạn có thể gọi Collections.sort trực tiếp mà không cần truyền thêm tham số nào.
- Collections.sort sẽ thay đổi danh sách gốc và sắp xếp các phần tử theo thứ tự được xác định bởi giao diện Comparable hoặc Comparator.
5. Tóm lại
Khi xử lý sắp xếp, lựa chọn giữa Comparable và Comparator phụ thuộc vào ngữ cảnh cụ thể và yêu cầu của ứng dụng. Comparable được sử dụng khi đối tượng có khả năng tự xác định cách sắp xếp, trong khi Comparator thích hợp khi bạn muốn xác định các tiêu chí sắp xếp mà không muốn can thiệp vào mã nguồn của lớp đối tượng.
Sử dụng khéo léo giữa Comparable và Comparator cùng với Collections.sort sẽ giúp chúng ta tận dụng tối đa khả năng sắp xếp linh hoạt và hiệu quả trong lập trình Java.
All rights reserved