Comparators and Applications in JAVA

Paras kaushikParas kaushik
5 min read

Understanding Comparator

A Comparator is an functional interface used to order objects of a user-defined class. It provides a method compare(T o1, T o2) that must be overridden to define the sorting logic.

Syntax

  1. Using Anonymous Classes
Comparator<Type> comparator = new Comparator<Type>() {
    @Override
    public int compare(Type o1, Type o2) {
        // comparison logic
        return comparisonResult;
    }
};
  1. Using Lambda Expressions
Comparator<Type> comparator = (Type o1, Type o2) -> {
    // comparison logic
    return comparisonResult;
};

Example: Sorting by Age and then by Name

import java.util.*;

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + ": " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>(Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 30),
            new Person("Charlie", 25)
        ));

        // Custom order: first by age, then by name
        Comparator<Person> comparator = new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                if (p1.age != p2.age) {
                    return Integer.compare(p1.age, p2.age);
                } else {
                    return p1.name.compareTo(p2.name);
                }
            }
        };

        Collections.sort(people, comparator);
 Collections.sort(people,(p1,p2)->
     Integer.compare(p1.age, p2.age));//Ascending

Collections.sort(people,(p1,p2)-> 
    Integer.compare(p2.age, p1.age));//Descending
        //First by name then age
        Collections.sort(people,(p1,p2)-> 
        ((p1.name==p2.name) ? 
    Integer.compare(p1.age, p2.age)
        :p1.name.compareTo(p2.name)));//Descending

        System.out.println(people);

    }
}

Sorting Using Lambda Expressions

1. ArrayList

import java.util.*;

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + ": " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>(Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 35)
        ));

        // Sort by age in ascending order
        people.sort((Person p1, Person p2) -> 
            Integer.compare(p1.age, p2.age));
        System.out.println("Sorted by age (ascending): " + people);

        // Sort by age in descending order
        people.sort((Person p1, Person p2) -> 
            Integer.compare(p2.age, p1.age));
        System.out.println("Sorted by age (descending): " + people);

        // Custom order: first by age, then by name
        people.sort((Person p1, Person p2) -> {
            int ageComparison = Integer.compare(p1.age, p2.age);
            if (ageComparison != 0) {
                return ageComparison;
            }
            return p1.name.compareTo(p2.name);
        });
        System.out.println("Custom order (by age then name): " + people);
    }
}

2. LinkedList

import java.util.*;

public class Main {
    public static void main(String[] args) {
        LinkedList<Person> people = new LinkedList<>(Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 35)
        ));

        // Sort by age in ascending order
        people.sort((Person p1, Person p2) -> Integer.compare(p1.age, p2.age));
        System.out.println("Sorted by age (ascending): " + people);

        // Sort by age in descending order
        people.sort((Person p1, Person p2) -> Integer.compare(p2.age, p1.age));
        System.out.println("Sorted by age (descending): " + people);

        // Custom order: first by age, then by name
        people.sort((Person p1, Person p2) -> {
            int ageComparison = Integer.compare(p1.age, p2.age);
            if (ageComparison != 0) {
                return ageComparison;
            }
            return p1.name.compareTo(p2.name);
        });
        System.out.println("Custom order (by age then name): " + people);
    }
}

3. PriorityQueue

import java.util.*;

public class Main {
    public static void main(String[] args) {
PriorityQueue<Person> queue =
new PriorityQueue<>
((Person p1, Person p2) -> Integer.compare(p1.age, p2.age));

 PriorityQueue<Person> queue =
 new PriorityQueue<>
((Person p1, Person p2) -> p1.name.compareTo(p2.name));

        queue.add(new Person("Alice", 30));
        queue.add(new Person("Bob", 25));
        queue.add(new Person("Charlie", 35));

        while (!queue.isEmpty()) {
            System.out.println(queue.poll());
        }
    }
}

4. Deque and ArrayDeque

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Deque<Person> deque = new ArrayDeque<>(Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 35)
        ));
// will have to convert to list to run ops on it 
// the constructor of list takes ANY collection to init from
        List<Person> sortedList = new ArrayList<>(deque);

        // Sort by age in ascending order
        sortedList.sort((Person p1, Person p2) -> Integer.compare(p1.age, p2.age));
        System.out.println("Sorted by age (ascending): " + sortedList);

        // Sort by age in descending order
        sortedList.sort((Person p1, Person p2) -> Integer.compare(p2.age, p1.age));
        System.out.println("Sorted by age (descending): " + sortedList);

        // Custom order: first by age, then by name
        sortedList.sort((Person p1, Person p2) -> {
            int ageComparison = Integer.compare(p1.age, p2.age);
            if (ageComparison != 0) {
                return ageComparison;
            }
            return p1.name.compareTo(p2.name);
        });
        System.out.println("Custom order (by age then name): " + sortedList);
    }
}

5. HashSet and TreeSet

For HashSet, we need to convert it to a List for sorting, and for TreeSet, we can use a Comparator in the constructor:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Set<Person> peopleSet = new HashSet<>(Arrays.asList(
            new Person("Alice", 30),
            new Person("Bob", 25),
            new Person("Charlie", 35)
        ));

        // Convert to List and sort by age in ascending order
        List<Person> sortedList = new ArrayList<>(peopleSet);
        sortedList.sort((Person p1, Person p2) -> Integer.compare(p1.age, p2.age));
        System.out.println("HashSet sorted by age (ascending): " + sortedList);

        // TreeSet with custom comparator (sort by age in descending order)
        TreeSet<Person> sortedSet = new TreeSet<>((Person p1, Person p2) -> Integer.compare(p2.age, p1.age));
        sortedSet.addAll(peopleSet);
        System.out.println("TreeSet sorted by age (descending): " + sortedSet);
    }
}

6. HashMap and TreeMap

Sorting a HashMap by values:

javaCopy codeimport java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Person> peopleMap = new HashMap<>();
        peopleMap.put("a", new Person("Alice", 30));
        peopleMap.put("b", new Person("Bob", 25));
        peopleMap.put("c", new Person("Charlie", 35));

        // TreeMap with custom comparator for values (sort by age in ascending order)
        TreeMap<String, Person> sortedByAgeMap = new TreeMap<>((String k1, String k2) -> {
            return Integer.compare(peopleMap.get(k1).age, peopleMap.get(k2).age);
        });
        sortedByAgeMap.putAll(peopleMap);

        System.out.println("TreeMap sorted by age (ascending): " + sortedByAgeMap);

        // TreeMap with custom comparator for values (sort by age in descending order)
        TreeMap<String, Person> sortedByAgeDescMap = new TreeMap<>((String k1, String k2) -> {
            return Integer.compare(peopleMap.get(k2).age, peopleMap.get(k1).age);
        });
        sortedByAgeDescMap.putAll(peopleMap);

        System.out.println("TreeMap sorted by age (descending): " + sortedByAgeDescMap);
    }
}
0
Subscribe to my newsletter

Read articles from Paras kaushik directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Paras kaushik
Paras kaushik

Hello, I'm Paras Kaushik! ๐Ÿ‘‹ I'm a dedicated software engineer based in India, specializing in C++ and proficient in the MERN stack. ๐Ÿค Interested in collaborating on innovative projects that require my technical expertise. ๐Ÿ’ฌ Passionate about participating in discussions related to software architecture and best practices. ๐Ÿ“ง Feel free to reach out to me via email: [paraskaushik12@gmail.com] ๐Ÿ”— Connect with me on LinkedIn: [https://www.linkedin.com/in/the-paras-kaushik/]