Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Java Program เรียงลำดับ ArrayList ของ Custom Objects ตาม Property

การเรียงลำดับ Custom Objects ใน ArrayList

เมื่อมี List ของ Object ต้องการเรียงตาม Property เฉพาะ (เช่น เรียงชื่อ A-Z, เรียงอายุ น้อยไปมาก) ใช้ Comparator หรือ Comparable

2 วิธีหลัก

1. Comparable Interface (Natural Ordering) - ใน Class เอง

public class Student implements Comparable {
    String name;
    int age;
    
    // ... constructor, getters
    
    @Override
    public int compareTo(Student other) {
        return this.name.compareTo(other.name); // เรียงตามชื่อ A-Z
    }
}

// ใช้งาน
List students = new ArrayList<>();
students.sort(null); // ใช้ Natural Ordering (compareTo)
Collections.sort(students); // วิธีเก่า

2. Comparator (Custom Ordering) - แยกนอก Class ⭐ แนะนำ

// Lambda (Java 8+)
list.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));

// Method Reference
list.sort(Comparator.comparing(Student::getName));

// หลายเงื่อนไข (ThenComparing)
list.sort(Comparator
    .comparing(Student::getAge)
    .thenComparing(Student::getName));

// Descending
list.sort(Comparator.comparing(Student::getAge).reversed());

ตัวอย่างที่ 1: ใช้ Comparator ใน main

import java.util.*;

class CustomObject {
    private String customProperty;
    
    public CustomObject(String property) {
        this.customProperty = property;
    }
    
    public String getCustomProperty() {
        return this.customProperty;
    }
}

public class Demo {
    public static void print(ArrayList list) {
        for (CustomObject obj : list) {
            System.out.println(obj.getCustomProperty());
        }
    }
    
    public static void sort(ArrayList list) {
        list.sort((obj1, obj2) -> 
            obj1.getCustomProperty().compareTo(obj2.getCustomProperty())
        );
    }
    
    public static void add(ArrayList list) {
        list.add(new CustomObject("Java"));
        list.add(new CustomObject("Scala"));
        list.add(new CustomObject("Python"));
        list.add(new CustomObject("Mysql"));
    }
    
    public static void main(String[] args) {
        System.out.println("Required packages have been imported");
        
        ArrayList inputList = new ArrayList<>();
        add(inputList);
        
        System.out.println("The list is defined as ");
        print(inputList);
        
        sort(inputList);
        
        System.out.println("\nThe list after sorting values: ");
        print(inputList);
    }
}

ผลลัพธ์

Required packages have been imported
The list is defined as
Java
Scala
Python
Mysql

The list after sorting values:
Java
Mysql
Python
Scala

ตัวอย่างที่ 2: Inline ใน main (Modern Java)

import java.util.*;

class CustomObject {
    private String customProperty;
    public CustomObject(String property) { this.customProperty = property; }
    public String getCustomProperty() { return this.customProperty; }
}

public class Demo {
    public static void main(String[] args) {
        System.out.println("Required packages have been imported");
        
        ArrayList inputList = new ArrayList<>();
        inputList.add(new CustomObject("Java"));
        inputList.add(new CustomObject("Scala"));
        inputList.add(new CustomObject("Python"));
        inputList.add(new CustomObject("Mysql"));
        
        System.out.println("The list is defined as ");
        for (CustomObject obj : inputList) {
            System.out.println(obj.getCustomProperty());
        }
        
        // Sort ใช้ Comparator.comparing (Clean & Readable)
        inputList.sort(Comparator.comparing(CustomObject::getCustomProperty));
        
        System.out.println("\nThe list after sorting values: ");
        for (CustomObject obj : inputList) {
            System.out.println(obj.getCustomProperty());
        }
    }
}

Comparator Patterns ที่น่าสนใจ

Null-safe Sorting

// Nulls First
list.sort(Comparator.comparing(CustomObject::getCustomProperty, 
    Comparator.nullsFirst(String::compareTo)));

// Nulls Last
list.sort(Comparator.comparing(CustomObject::getCustomProperty, 
    Comparator.nullsLast(String::compareTo)));

หลาย Property (Chaining)

// เรียง Age ASC แล้ว Name ASC
list.sort(Comparator
    .comparing(Student::getAge)
    .thenComparing(Student::getName));

// เรียง Age DESC แล้ว Name ASC
list.sort(Comparator
    .comparing(Student::getAge).reversed()
    .thenComparing(Student::getName));

Custom Comparator Class (Reusable)

public class StudentNameComparator implements Comparator {
    @Override
    public int compare(Student s1, Student s2) {
        return s1.getName().compareTo(s2.getName());
    }
}

// ใช้งาน
list.sort(new StudentNameComparator());

Comparable vs Comparator

ด้าน Comparable Comparator
Interface java.lang.Comparable java.util.Comparator
Method compareTo(T o) compare(T o1, T o2)
ตำแหน่ง ภายใน Class (this vs other) Class แยกหรือ Lambda
Sorting Orders 1 วิธี (Natural Order) หลายวิธีได้
Modification ต้องแก้ Class ไม่ต้องแก้ Class
ใช้กับ Core Domain Objects Third-party Classes, Multiple Orders

Performance Notes

  • List.sort() ใช้ TimSort (Hybrid Merge + Insertion Sort) - O(n log n)
  • Stable Sort - รักษาลำดับเดิมของ Equal Elements
  • Comparator.comparing() สร้าง Comparator แบบ Lazy, ประสิทธิภาพดี
  • หลีกเลี่ยงการสร้าง Object ใหม่ใน Comparator (GC Pressure)

สรุป

  • ใช้ Comparator.comparing() + Lambda/Method Reference (Java 8+)
  • รองรับ Chaining: thenComparing(), reversed(), nullsFirst/Last()
  • แยก Comparator ออกจาก Domain Class (Separation of Concerns)
  • List.sort() ใช้ TimSort Stable O(n log n)
  • Implements Comparable เมื่อมี "Natural Order" ชัดเจน