Understanding the Comparable Interface

Definition:

The Comparable interface in Java allows objects of a class to be compared with each other to define a natural ordering. A class that implements Comparable must override the compareTo() method.

compareTo() Method Signature:

public int compareTo(T o);

compareTo() returns:

  • Positive integer (+ve): if the current object is greater than the object being compared.
  • Negative integer (-ve): if the current object is less than the object being compared.
  • Zero (0): if the current object is equal to the object being compared.

This mechanism is used by sorting algorithms to determine the order of elements.

Sorting Rule:

  • If compareTo() returns positive (+ve): the current object is considered greater and will be placed after the compared object in a sorted collection.
  • If compareTo() returns negative (-ve): the current object is considered smaller and will be placed before the compared object.
  • If compareTo() returns 0: both objects are considered equal.

NOTE:

Obj1.compareTo(Obj2)
If Obj2 comes before the Obj1 then compareTo() return +ve else -ve.
Code Example
Output
Employees sorted by name (TreeSet):
Employee{name='Alice', id=102}
Employee{name='Bob', id=104}
Employee{name='John', id=101}
Employee{name='Zara', id=103}

Explanation:

Tree Explanation with Comparison Steps:

  • Insert "John":
    • No other element exists, so "John" becomes the root of the tree.
  • Insert "Alice":
    • "Alice".compareTo("John") returns a negative value (-ve), meaning "Alice" is less than "John". So, "Alice" goes to the left of "John".
  • Insert "Zara":
    • "Zara".compareTo("John") returns a positive value (+ve), meaning "Zara" is greater than "John". So, "Zara" goes to the right of "John".
  • Insert "Bob":
    • "Bob".compareTo("John") returns a negative value (-ve), meaning "Bob" is less than "John".
    • Next, "Bob".compareTo("Alice") returns a positive value (+ve), meaning "Bob" is greater than "Alice". Therefore, "Bob" goes to the right of "Alice".
The insertion sequence builds the following tree:   
        John
       /    \
   Alice    Zara
       \
       Bob
Inorder Traversal: [Alice, Bob, John< Zara]

Output

Before Sorting by Price:
Product{name='Laptop', price=800.0}
Product{name='Smartphone', price=500.0}
Product{name='Headphones', price=50.0}
Product{name='Monitor', price=300.0}

After Sorting by Price:
Product{name='Headphones', price=50.0}
Product{name='Monitor', price=300.0}
Product{name='Smartphone', price=500.0}
Product{name='Laptop', price=800.0}

Explanation:

First Insertion: Laptop (Price 800.00)

  • The list starts with the root node: "Laptop" at 800.00.

Second Insertion: Smartphone (Price 500.00)

  • The price of "Smartphone" (500.00) is less than "Laptop" (800.00).
    • 500.00.compareTo(800.00)
    • So, "Smartphone" would go to the left of "Laptop", just like how a binary tree works.

Third Insertion: Headphones (Price 50.00)

  • The price of "Headphones" (50.00) is less than both "Laptop" (800.00) and "Smartphone" (500.00).
    • 50.00.compareTo(800.00)
    • 50.00.compareTo(500.00)
    • So, "Headphones" goes to the left of "Smartphone".

Fourth Insertion: Monitor (Price 300.00)

  • The price of "Monitor" (300.00) is less than "Laptop" (800.00), so compare it with "Smartphone" (500.00).
  • "Monitor" is less than "Smartphone" but greater than "Headphones" (50.00).
    • 300.00.compareTo(800.00)
    • 300.00.compareTo(500.00)
    • 300.00.compareTo(50.00)
    • So, "Monitor" goes to the right of "Headphones".
      (800.00)
         /
    (500.00)
      /
(50.00)
      \
     (300.00)
Inorder Traversal: [50, 300, 500, 800]