Tôi đang triển khai compareTo()
phương thức cho một lớp đơn giản như thế này (để có thể sử dụng Collections.sort()
và các tính năng khác được cung cấp bởi nền tảng Java):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
Tôi muốn thứ tự tự nhiên cho các đối tượng này là: 1) được sắp xếp theo tên và 2) được sắp xếp theo giá trị nếu tên giống nhau; cả hai so sánh nên không phân biệt chữ hoa chữ thường. Đối với cả hai trường, giá trị null là hoàn toàn chấp nhận được, vì vậy compareTo
không được phá vỡ trong các trường hợp này.
Giải pháp nảy sinh trong tâm trí là dọc theo các dòng sau (Tôi đang sử dụng "mệnh đề bảo vệ" ở đây trong khi các giải pháp khác có thể thích một điểm quay lại duy nhất, nhưng đó là điểm bên cạnh):
// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
if (this.name == null && other.name != null){
return -1;
}
else if (this.name != null && other.name == null){
return 1;
}
else if (this.name != null && other.name != null) {
int result = this.name.compareToIgnoreCase(other.name);
if (result != 0){
return result;
}
}
if (this.value == null) {
return other.value == null ? 0 : -1;
}
if (other.value == null){
return 1;
}
return this.value.compareToIgnoreCase(other.value);
}
Điều này thực hiện công việc, nhưng tôi không hoàn toàn hài lòng với mã này. Phải thừa nhận rằng nó không quá phức tạp, nhưng khá dài dòng và tẻ nhạt.
Câu hỏi là, làm thế nào bạn sẽ làm cho điều này ít dài dòng hơn (trong khi vẫn giữ được chức năng)? Vui lòng tham khảo các thư viện tiêu chuẩn Java hoặc Apache Commons nếu chúng giúp. Liệu lựa chọn duy nhất để làm cho điều này (một chút) đơn giản hơn là triển khai "NullSafeStringComparator" của riêng tôi và áp dụng nó để so sánh cả hai trường?
Chỉnh sửa 1-3 : Quyền của Eddie; đã sửa trường hợp "cả hai tên đều null" ở trên
Về câu trả lời được chấp nhận
Tôi đã hỏi câu hỏi này vào năm 2009, trên Java 1.6, và tại thời điểm đó , giải pháp JDK thuần túy của Eddie là câu trả lời được chấp nhận ưa thích của tôi. Tôi chưa bao giờ có vòng để thay đổi điều đó cho đến bây giờ (2017).
Ngoài ra còn có các giải pháp thư viện của bên thứ 3 Tập hợp Bộ sưu tập Apache Commons 2009 và Bộ sưu tập năm 2013, cả hai đều được đăng bởi tôi mà tôi thích vào một lúc nào đó.
Bây giờ tôi đã làm cho giải pháp Java 8 sạch của Lukasz Wiktor là câu trả lời được chấp nhận. Điều đó chắc chắn nên được ưu tiên nếu trên Java 8 và ngày nay Java 8 sẽ có sẵn cho gần như tất cả các dự án.