Skip to content

Comparaison

Comparaison#

Object comparison enables sorting, ranking, and organizing collections of objects. It establishes hierarchical relationships—defining not just equality, but what makes one object "greater than" or "less than" another.

Core Comparison Concepts#

Natural Ordering - Objects define their own comparison logic through interfaces like Comparable:

graph LR
    A[Object] --> B[implements Comparable]
    B --> C[compareTo method]
    C --> D[Returns: -1, 0, or +1]
    D --> E[Enables sorting]

    style A fill:#e3f2fd
    style C fill:#c8e6c9
    style E fill:#ffcdd2

Implement Comparable<Guitar> interface with compareTo() method:

public class Guitar implements Comparable<Guitar> {
    private String brand;
    private String model;
    private double price;

    public Guitar(String brand, String model, double price) {
        this.brand = brand;
        this.model = model;
        this.price = price;
    }

    @Override
    public int compareTo(Guitar other) {
        return Double.compare(this.price, other.price);
    }
}

// Create instances of Guitar
Guitar guitar1 = new Guitar("Fender", "Stratocaster", 1000.0);
Guitar guitar2 = new Guitar("Gibson", "Les Paul", 1500.0);

System.out.println(guitar1.compareTo(guitar2));  // Output: -1 (guitar1 is less than guitar2)
System.out.println(guitar2.compareTo(guitar1));  // Output: 1 (guitar2 is greater than guitar1)

Implement Comparable<Guitar> interface with compareTo() function:

class Guitar(val brand: String, val model: String, val price: Double) : Comparable<Guitar> {
    override fun compareTo(other: Guitar): Int {
        return price.compareTo(other.price)
    }
}

// Create instances of Guitar
val guitar1 = Guitar("Fender", "Stratocaster", 1000.0)
val guitar2 = Guitar("Gibson", "Les Paul", 1500.0)

println(guitar1.compareTo(guitar2))  // Output: -1 (guitar1 is less than guitar2)
println(guitar2.compareTo(guitar1))  // Output: 1 (guitar2 is greater than guitar1)

Implement custom compare() method for object comparison:

class Guitar {
    brand: string;
    model: string;
    price: number;

    constructor(brand: string, model: string, price: number) {
        this.brand = brand;
        this.model = model;
        this.price = price;
    }

    compare(other: Guitar): number {
        return this.price - other.price;
    }
}

// Create instances of Guitar
const guitar1 = new Guitar("Fender", "Stratocaster", 1000.0);
const guitar2 = new Guitar("Gibson", "Les Paul", 1500.0);

console.log(guitar1.compare(guitar2));  // Output: -500 (guitar1 is less than guitar2)
console.log(guitar2.compare(guitar1));  // Output: 500 (guitar2 is greater than guitar1)

Implement compareTo() method for object comparison:

class Guitar {
    String brand;
    String model;
    double price;

    Guitar(this.brand, this.model, this.price);

    int compareTo(Guitar other) {
        return price.compareTo(other.price);
    }
}

// Create instances of Guitar
Guitar guitar1 = Guitar("Fender", "Stratocaster", 1000.0);
Guitar guitar2 = Guitar("Gibson", "Les Paul", 1500.0);

print(guitar1.compareTo(guitar2));  // Output: -1 (guitar1 is less than guitar2)
print(guitar2.compareTo(guitar1));  // Output: 1 (guitar2 is greater than guitar1)

Implement Comparable protocol with < operator:

class Guitar: Comparable {
    var brand: String
    var model: String
    var price: Double

    init(brand: String, model: String, price: Double) {
        self.brand = brand
        self.model = model
        self.price = price
    }

    static func < (lhs: Guitar, rhs: Guitar) -> Bool {
        return lhs.price < rhs.price
    }
}

// Create instances of Guitar
let guitar1 = Guitar(brand: "Fender", model: "Stratocaster", price: 1000.0)
let guitar2 = Guitar(brand: "Gibson", model: "Les Paul", price: 1500.0)

print(guitar1 < guitar2)  // Output: true (guitar1 is less than guitar2)
print(guitar2 < guitar1)  // Output: false (guitar2 is not less than guitar1)

Implement __lt__ method for object comparison:

class Guitar:
    def __init__(self, brand, model, price):
        self.brand = brand
        self.model = model
        self.price = price

    def __lt__(self, other):
        return self.price < other.price

# Create instances of Guitar
guitar1 = Guitar("Fender", "Stratocaster", 1000.0)
guitar2 = Guitar("Gibson", "Les Paul", 1500.0)

print(guitar1 < guitar2)  # Output: True (guitar1 is less than guitar2)
print(guitar2 < guitar1)  # Output: False (guitar2 is not less than guitar1)

Custom Comparators - External comparison logic for multiple sorting strategies:

graph LR
    A[Collection] --> B[Comparator]
    B --> C[Custom comparison logic]
    C --> D[Multiple sorting options]
    D --> E[Price, Name, Date, etc.]

    style A fill:#e3f2fd
    style C fill:#fff3e0
    style E fill:#ffcdd2

Use Comparator for custom sorting strategies:

public class Guitar {
    private String brand;
    private String model;
    private double price;
    private int year;

    public Guitar(String brand, String model, double price, int year) {
        this.brand = brand;
        this.model = model;
        this.price = price;
        this.year = year;
    }

    // Getters
    public String getBrand() { return brand; }
    public String getModel() { return model; }
    public double getPrice() { return price; }
    public int getYear() { return year; }
}

// Multiple comparators for different sorting strategies
Comparator<Guitar> byPrice = Comparator.comparing(Guitar::getPrice);
Comparator<Guitar> byYear = Comparator.comparing(Guitar::getYear).reversed();
Comparator<Guitar> byBrandThenPrice = Comparator.comparing(Guitar::getBrand)
                                               .thenComparing(Guitar::getPrice);

// Usage
List<Guitar> guitars = Arrays.asList(
    new Guitar("Fender", "Stratocaster", 1000.0, 2020),
    new Guitar("Gibson", "Les Paul", 1500.0, 2019),
    new Guitar("Fender", "Telecaster", 800.0, 2021)
);

guitars.sort(byPrice);        // Sort by price
guitars.sort(byYear);         // Sort by year (newest first)
guitars.sort(byBrandThenPrice); // Sort by brand, then price

Use Comparator for custom sorting strategies:

data class Guitar(val brand: String, val model: String, val price: Double, val year: Int)

// Multiple comparators for different sorting strategies
val byPrice = compareBy<Guitar> { it.price }
val byYear = compareByDescending<Guitar> { it.year }
val byBrandThenPrice = compareBy<Guitar> { it.brand }.thenBy { it.price }

// Usage
val guitars = listOf(
    Guitar("Fender", "Stratocaster", 1000.0, 2020),
    Guitar("Gibson", "Les Paul", 1500.0, 2019),
    Guitar("Fender", "Telecaster", 800.0, 2021)
)

guitars.sortedWith(byPrice)        // Sort by price
guitars.sortedWith(byYear)         // Sort by year (newest first)
guitars.sortedWith(byBrandThenPrice) // Sort by brand, then price

Use custom comparison functions for different sorting strategies:

class Guitar {
    brand: string;
    model: string;
    price: number;
    year: number;

    constructor(brand: string, model: string, price: number, year: number) {
        this.brand = brand;
        this.model = model;
        this.price = price;
        this.year = year;
    }
}

// Multiple comparison functions for different sorting strategies
const byPrice = (a: Guitar, b: Guitar) => a.price - b.price;
const byYear = (a: Guitar, b: Guitar) => b.year - a.year; // Newest first
const byBrandThenPrice = (a: Guitar, b: Guitar) => {
    if (a.brand !== b.brand) return a.brand.localeCompare(b.brand);
    return a.price - b.price;
};

// Usage
const guitars = [
    new Guitar("Fender", "Stratocaster", 1000.0, 2020),
    new Guitar("Gibson", "Les Paul", 1500.0, 2019),
    new Guitar("Fender", "Telecaster", 800.0, 2021)
];

guitars.sort(byPrice);        // Sort by price
guitars.sort(byYear);         // Sort by year (newest first)
guitars.sort(byBrandThenPrice); // Sort by brand, then price

Use Comparator functions for custom sorting strategies:

class Guitar {
    String brand;
    String model;
    double price;
    int year;

    Guitar(this.brand, this.model, this.price, this.year);
}

// Multiple comparison functions for different sorting strategies
int byPrice(Guitar a, Guitar b) => a.price.compareTo(b.price);
int byYear(Guitar a, Guitar b) => b.year.compareTo(a.year); // Newest first
int byBrandThenPrice(Guitar a, Guitar b) {
    int brandComparison = a.brand.compareTo(b.brand);
    if (brandComparison != 0) return brandComparison;
    return a.price.compareTo(b.price);
}

// Usage
List<Guitar> guitars = [
    Guitar("Fender", "Stratocaster", 1000.0, 2020),
    Guitar("Gibson", "Les Paul", 1500.0, 2019),
    Guitar("Fender", "Telecaster", 800.0, 2021)
];

guitars.sort(byPrice);        // Sort by price
guitars.sort(byYear);         // Sort by year (newest first)
guitars.sort(byBrandThenPrice); // Sort by brand, then price

Use custom comparison closures for different sorting strategies:

class Guitar {
    var brand: String
    var model: String
    var price: Double
    var year: Int

    init(brand: String, model: String, price: Double, year: Int) {
        self.brand = brand
        self.model = model
        self.price = price
        self.year = year
    }
}

// Multiple comparison closures for different sorting strategies
let byPrice = { (a: Guitar, b: Guitar) -> Bool in a.price < b.price }
let byYear = { (a: Guitar, b: Guitar) -> Bool in a.year > b.year } // Newest first
let byBrandThenPrice = { (a: Guitar, b: Guitar) -> Bool in
    if a.brand != b.brand { return a.brand < b.brand }
    return a.price < b.price
}

// Usage
let guitars = [
    Guitar(brand: "Fender", model: "Stratocaster", price: 1000.0, year: 2020),
    Guitar(brand: "Gibson", model: "Les Paul", price: 1500.0, year: 2019),
    Guitar(brand: "Fender", model: "Telecaster", price: 800.0, year: 2021)
]

let sortedByPrice = guitars.sorted(by: byPrice)
let sortedByYear = guitars.sorted(by: byYear)
let sortedByBrandThenPrice = guitars.sorted(by: byBrandThenPrice)

Use custom key functions and comparison functions for different sorting strategies:

class Guitar:
    def __init__(self, brand, model, price, year):
        self.brand = brand
        self.model = model
        self.price = price
        self.year = year

# Multiple comparison functions for different sorting strategies
def by_price(guitar):
    return guitar.price

def by_year(guitar):
    return -guitar.year  # Negative for descending order (newest first)

def by_brand_then_price(guitar):
    return (guitar.brand, guitar.price)

# Usage
guitars = [
    Guitar("Fender", "Stratocaster", 1000.0, 2020),
    Guitar("Gibson", "Les Paul", 1500.0, 2019),
    Guitar("Fender", "Telecaster", 800.0, 2021)
]

guitars.sort(key=by_price)        # Sort by price
guitars.sort(key=by_year)         # Sort by year (newest first)
guitars.sort(key=by_brand_then_price) # Sort by brand, then price

Comparison Benefits - Enables efficient data operations:

graph TD
    A[Comparison] --> B[Sorting]
    A --> C[Searching]
    A --> D[Priority Queues]
    A --> E[Binary Search]

    B --> F[Collections.sort]
    C --> G[Binary search trees]
    D --> H[Task scheduling]
    E --> I[Fast lookups]

    style A fill:#e3f2fd
    style F fill:#c8e6c9
    style G fill:#c8e6c9
    style H fill:#c8e6c9
    style I fill:#c8e6c9

When to Use Each Approach#

Use Comparable when:

  • There's one obvious "natural" ordering for your objects
  • You control the class and can modify it
  • The ordering makes sense for the object's primary purpose

Use Comparator when:

  • You need multiple sorting strategies
  • You can't modify the original class
  • The sorting criteria are context-dependent
  • You want to sort by different fields for different use cases