Comparator và Comparable trong Java
Comparator và Comparable trong Java
Trong
một danh sách, một mảng, khi muốn sắp xếp, ta phải áp dụng một số kỹ thuật cơ bản
(Bubble sort, Quick sort, Insertion sort,…) để sắp xếp 1 danh sách. Thực tế,
Java cung cấp cho bạn một hàm dùng để sắp xếp, bạn không cần phải tự mình xây dựng
thuật toán sắp xếp nữa. Hàm này sẽ giúp bạn giải quyết các mảng, các danh sách có
kiểu dữ liệu nguyên thủy hoặc Wrapper tương ứng. Hãy xem ví dụ sau:
Kết
quả in ra màn hình như sau:
Như
các bạn thấy, mảng arr đã được sắp xếp theo thứ tự tăng dần thông qua hàm
Arrays.sort() và danh sách list đã được sắp xếp theo thứ tự tăng dần thông qua
hàm Collections.sort(). Bạn chỉ cần thả một mảng/ danh sách vào hàm tương ứng để
được sắp xếp
Vấn
đề đặt ra: Nếu kiểu dữ liệu ngoài kiểu nguyên thủy và Wrapper tương ứng ra thì
sao?
Ta
có một trường hợp như sau:
Và
kết quả là:
Vì
sao lại như vậy nhỉ? Hãy đặt nghi vấn ngược xem nếu nó chạy được thì nó sẽ sắp
xếp như thế nào? Khi nào thì một đối tượng A lớn hơn một đối tượng B? Tên của A
đứng trước B, hay tuổi của A nhỏ hơn B? Chính vấn đề về việc định nghĩa một đối
tượng lớn hơn đối tượng khác là nguyên nhân, vì mỗi đối tượng được thể hiện
qua nhiều thuộc tính khác nhau (Ví dụ đối tượng Học sinh được thể hiện qua Tên,
Tuổi) nên việc xét đối tượng nào lớn hơn phải phụ thuộc vào cách người sử dụng định
nghĩa.
Và
thế là, Comparable ra đời
COMPARABLE
Comparable
cho phép chúng ta định nghĩa về một đối tượng lớn hơn so với đối tượng khác là
như thế nào. Chúng ta sẽ implements interface Comparable vào class của đối tượng
cần xét và override hàm compareTo(T obj). Để hiểu rõ về nó, hãy xem ví dụ sau:
Ta
sẽ có quy ước sau: nếu this.age nhỏ hơn that.age trả về số âm, this.age = that.age
trả về 0, this.age > that.age trả về số dương. Theo quy tắc trên, ta sẽ sắp
xếp được danh sách theo thứ tự tăng dần. Kết quả trả về như sau:
Vấn
đề đã được giải quyết! Thế nhưng, một vấn đề khác lại xuất hiện, xuất phát từ
thực tế. Giả sử một giáo viên cần danh sách sắp xếp theo tên để gọi tên theo bảng
chữ cái, hay một địa phương cần danh sách sắp xếp theo tuổi để lựa chọn thành
phần đi khám nghĩa vụ quân sự. Comparable chỉ cung cấp một cách định nghĩa đối
tượng lớn hơn đối tượng. Vì thế, Comparator sẽ giải quyết bài toán này.
COMPARATOR
Comparator
là một interface giúp cho chúng ta giải quyết bài toán sắp xếp tùy vào những yêu
cầu khác nhau. Chúng ta cần phải tạo một class implements Comparator, override
hàm compare(T obj1, T obj2). Sau đó trong hàm Arrays.sort(), ngoài việc thêm vào
một danh sách, bạn sẽ thêm đối tượng thuộc class ban nãy bạn đã tạo.
Để
đơn giản, mời bạn xem ví dụ bên dưới:
Kết
quả như sau:
Các
quy ước để chuỗi tăng dần giống như Comparator. Các bạn cố gắng đọc rồi suy ngẫm
để hiểu thêm. Mình sẽ giải thích ngắn gọn về tư tưởng của Comparable và Comparator
ở phần kết.
SO SÁNH GIỮA COMPARABLE VÀ
COMPARATOR
1.
Comparable chỉ so sánh hai đối tượng theo
một cách duy nhất, trong khi đó Comparator so sánh theo nhiều cách khác nhau
2.
Comparable nằm trong java.lang trong khi đó
Comparator nằm trong java.util (java.lang là package mặc định, mang tính cơ bản.
Còn java.util là package xem như tính năng mở rộng. Chi tiết java.util và java.lang
xem tại đây: Sự khác biệt giữa java.lang và java.util)
3.
Trên phương diện người dùng, khi sử dụng không
có bất kỳ sự thay đổi nào (Arrays.sort() vẫn giữ nguyên như kiểu nguyên thủy,
Wrapper) trong khi đó Comparator, người dùng phải sử dụng một class implements
Comparator
4.
Trong Comparable, class của đối tượng
trong danh sách cần sắp xếp bị thay đổi (cụ thể là implements Comparable và override
phương thức compareTo()) trong khi đó Comparator, class của đối tượng không bị
thay đổi.
GIẢI THÍCH VỀ MẶT Ý TƯỞNG
Khi
chúng ta sắp xếp các đối tượng, chúng ta sẽ phải xác định việc so sánh đối tượng
(cái nào lớn hơn cái nào). Comparable giúp chúng ta định nghĩa điều đó. Đó cũng
có thể xem như là một định nghĩa mặc định, được cài đặt trực tiếp (phía người
thực hiện). Thế nhưng, trong đời sống thực tế, có thể có nhiều cách định nghĩa
khác nhau. Vậy nên, trong quá trình sắp xếp, chúng ta sẽ truyền vào một Comparator,
chính là đưa vào cách chúng ta (phía người dùng) định nghĩa về nó, để nó hiểu và
sắp xếp theo cách đó. Lưu ý rằng Comparable và Comparator chỉ là cách so sánh,
không phải là cách sắp xếp, dễ thấy nhất đó là hàm compareTo() của lớp String,
nó cũng thuộc Comparable, và đó chỉ là cách so sánh. Cách sắp xếp như thế nào,
nó thuộc về Arrays.sort() và Collections.sort(). Vậy nên, khi nhắc đến
Comparable hay Comparator, bạn hãy nhớ đặc điểm của đó là định nghĩa so sánh nhé,
và nó gắn liền với việc sắp xếp.
Và đó cũng chính là tổng
kết của bài viết này. Thấy hay thì cho 1 like nhá <3!
Nội dung bài viết thuộc về Lê Công Diễn.
Người viết: Lê
Công Diễn
Mang đi nhớ ghi nguồn
Không tệ. Rất ý nghĩa, rất hay ho. Thanks nhé!
Trả lờiXóaCảm ơn nhiều!
XóaNhận xét này đã bị tác giả xóa.
Trả lờiXóa