Java ProgramsCollectionsSort Objects Using Comparable

Sort Objects Using Comparable in Java

beginner·  Collections  ·  Comparator & Comparable

Problem

Once a class implements Comparable and defines its natural ordering, Collections.sort() can sort a whole list of them directly, with no extra sorting logic supplied at the call site.

Given a list of Product objects that implement Comparable by price, sort the list into ascending order.

Input
[Laptop: $999.99, Mouse: $19.99, Keyboard: $49.99]
Output
Mouse: $19.99 Keyboard: $49.99 Laptop: $999.99

Java Program

Java
import java.util.ArrayList; import java.util.Collections; import java.util.List; class Product implements Comparable<Product> { String name; double price; Product(String name, double price) { this.name = name; this.price = price; } public int compareTo(Product other) { return Double.compare(this.price, other.price); } @Override public String toString() { return name + ": $" + price; } } public class SortObjectsUsingComparable { public static void main(String[] args) { List<Product> products = new ArrayList<>(); products.add(new Product("Laptop", 999.99)); products.add(new Product("Mouse", 19.99)); products.add(new Product("Keyboard", 49.99)); Collections.sort(products); // relies on Product's own compareTo(), no separate Comparator needed for (Product p : products) { System.out.println(p); } } }

Output

Mouse: $19.99 Keyboard: $49.99 Laptop: $999.99

Core Logic

Because Product already defines its own natural ordering through compareTo(), Collections.sort() can rearrange the whole list without being told how to compare two products.

How It Works
  1. 1class Product implements Comparable<Product> defines compareTo() using Double.compare(this.price, other.price), making price the natural ordering.
  2. 2Collections.sort(products) is called with no second argument — no Comparator is supplied, so it falls back to each element's own compareTo().
  3. 3Internally, the sort algorithm calls compareTo() between pairs of Product objects to decide their relative order, the same way it would compare Integers or Strings.
  4. 4After sorting, the list itself is rearranged in place — products now holds the same three objects in ascending price order.
Starting from [Laptop, Mouse, Keyboard], sorting by each product's compareTo() reorders them to [Mouse, Keyboard, Laptop], from cheapest to most expensive.
💡

Key Point: Collections.sort(list) with no second argument only compiles when the list's element type implements Comparable — this is the compiler enforcing that a natural ordering actually exists before it lets you sort by it.

Complexity
Time Complexity: O(n log n)Space Complexity: O(1)

Why: Collections.sort() uses a comparison-based sort with O(n log n) time; sorting an ArrayList in place needs no extra storage proportional to the list's size.

Key Concepts

Comparable<T>Collections.sort()natural ordering

Approach 2: Java 8

Java
import java.util.List; import java.util.stream.Collectors; class ProductRecord implements Comparable<ProductRecord> { String name; double price; ProductRecord(String name, double price) { this.name = name; this.price = price; } public int compareTo(ProductRecord other) { return Double.compare(this.price, other.price); } @Override public String toString() { return name + ": $" + price; } } public class SortObjectsUsingComparableStream { public static void main(String[] args) { List<ProductRecord> products = List.of( new ProductRecord("Laptop", 999.99), new ProductRecord("Mouse", 19.99), new ProductRecord("Keyboard", 49.99) ); // Relies on ProductRecord's own compareTo(), collecting into a new sorted list List<ProductRecord> sorted = products.stream() .sorted() .collect(Collectors.toList()); for (ProductRecord p : sorted) { System.out.println(p); } } }

Output

Mouse: $19.99 Keyboard: $49.99 Laptop: $999.99

Core Logic

Streaming the list and calling the no-argument sorted() relies on Product's own compareTo() the same way Collections.sort() does, but produces a new sorted list instead of reordering the original.

How It Works
  1. 1products.stream() opens a stream over the list's elements.
  2. 2.sorted() with no arguments sorts using each element's natural ordering — Product's own compareTo() — exactly like Collections.sort(products) does.
  3. 3.collect(Collectors.toList()) gathers the sorted stream into a brand-new List.
  4. 4Unlike the primary approach's in-place Collections.sort(), the original products list is left in its original order.
Streaming and sorting [Laptop, Mouse, Keyboard] by their natural (price) ordering collects into [Mouse, Keyboard, Laptop], the same ascending order the primary approach produces.
💡

Key Point: sorted() with no arguments only compiles when the stream's element type implements Comparable, the same compile-time requirement Collections.sort(list) has — the difference here is purely in-place mutation versus a freshly-collected list.

Complexity
Time Complexity: O(n log n)Space Complexity: O(n)

Why: sorted() still performs the same comparison-based sort as Collections.sort(), and collect() additionally builds a new list to hold the result, unlike the primary approach's in-place sort.

Key Concepts

Streamsorted()Collectors.toList()

Related Programs