ฉันใช้compareTo()
วิธีการสำหรับชั้นเรียนอย่างง่ายเช่นนี้ (เพื่อให้สามารถใช้Collections.sort()
และสินค้าอื่น ๆ ที่เสนอโดยแพลตฟอร์ม Java):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
ฉันต้องการลำดับธรรมชาติสำหรับวัตถุเหล่านี้จะเป็น: 1) เรียงตามชื่อและ 2) เรียงตามค่าถ้าชื่อเหมือนกัน; การเปรียบเทียบทั้งสองควรคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ สำหรับเขตข้อมูลทั้งสองค่าเป็นที่ยอมรับอย่างสมบูรณ์ดังนั้นcompareTo
จะต้องไม่หยุดในกรณีเหล่านี้
วิธีแก้ปัญหาที่ควรคำนึงถึงนั้นเป็นไปตามลำดับต่อไปนี้ (ฉันใช้ "คำสั่งป้องกัน" ที่นี่ในขณะที่คนอื่น ๆ อาจต้องการจุดส่งคืนเดียว แต่นั่นอยู่ด้านข้าง)
// 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);
}
ทำงานได้ แต่ฉันไม่พอใจกับรหัสนี้อย่างสมบูรณ์ เป็นที่ยอมรับว่ามันไม่ซับซ้อนมากแต่ค่อนข้างละเอียดและน่าเบื่อ
คำถามคือคุณจะทำให้ verbose นี้น้อยลงได้อย่างไร (ในขณะที่รักษาการทำงาน) โปรดอ้างถึงไลบรารีมาตรฐาน Java หรือ Apache Commons หากพวกเขาช่วย ตัวเลือกเดียวที่ทำให้สิ่งนี้ง่ายขึ้นคือการใช้ "NullSafeStringComparator" ของฉันเองและใช้เพื่อเปรียบเทียบทั้งสองฟิลด์
แก้ไข 1-3 : Eddie's right; แก้ไขตัวอักษร "ทั้งสองชื่อเป็นโมฆะ" ด้านบน
เกี่ยวกับคำตอบที่ยอมรับ
ฉันถามคำถามนี้ย้อนกลับไปในปี 2009 บน Java 1.6 แน่นอนและในเวลานั้นโซลูชัน JDK บริสุทธิ์โดย Eddieเป็นคำตอบที่ฉันต้องการ ฉันไม่เคยเปลี่ยนเลยจนกระทั่งตอนนี้ (2017)
นอกจากนี้ยังมีโซลูชันห้องสมุดของบุคคลที่สาม - 2009 Apache Commons Collections one และ Guava 2013 ทั้งสองโพสต์โดยฉัน - ฉันชอบในบางช่วงเวลา
ตอนนี้ฉันสร้างโซลูชัน Java 8 ที่สะอาดโดย Lukasz Wiktorเป็นคำตอบที่ยอมรับได้ ที่ควรจะเป็นที่ต้องการอย่างแน่นอนถ้าใน Java 8 และวันนี้ Java 8 ควรจะสามารถใช้ได้กับโครงการเกือบทั้งหมด