You don’t know Comparators in-practice, Do You?
When I started learning about sorting objects in Java, I was bored with the interviewer’s favourite question—Comparable vs. Comparator.
So, I thought it was time to level up because merely knowing the difference between the above 2 interfaces will not make an efficient developer. As someone who has to write code, I need more substance to be able to put this to use every day.
So, I started to explore various coding problems that Comparators can solve. And that is what we will discuss today.
In Java, the Comparator interface defines custom ordering for objects. Using this interface, we can efficiently sort collections, arrays, and other data structures in a desired order.
When to Use the Comparator Interface:
The Comparator interface in Java provides a flexible way to define custom comparison logic for objects. It is used when:
- The class of the objects being compared does not implement the Comparable interface.
HELPS to define different comparison criteria for sorting without modifying the original class or implementing the
Comparable
interface.
- When you need different sorting criteria for different use cases or when you don’t have control over the class’s source code (e.g., if it’s part of a library). If you have control over the class and can modify its
compareTo
method to suit your needs, then go with Comparable.
Detailed GitHub documentation on Comparators — https://github.com/VarshaDas/Java-Code-Snippets/blob/main/ComparatorsDemo/README-Comparators.md
Relevant code links:
https://github.com/VarshaDas/Java-Code-Snippets/blob/main/ComparatorsDemo/ComparatorDemo.java
Coding Questions:
Let’s now see how we can incorporate Comparators and its APIs into our day-to-day coding problems.
But before that, a brief introduction to five important methods of the Comparator :
compare(T obj1, T obj2):
This method compares two objects for order.
It returns an int
value:
- Negative Integer: If
obj1
is considered less thanobj2
. - Zero: If
obj1
is considered equal toobj2
. - Positive Integer: If
obj1
is considered greater thanobj2
.
The compare method is the main method that needs to be implemented when creating a custom comparator. It defines the ordering of objects based on the logic specified in the implementation.
naturalOrder()
and reverseOrder()
:
Comparator.naturalOrder()
: Returns a comparator that imposes the natural ordering of the elements.
The “natural ordering” is the default ordering that is inherent to the data type. For primitive types and some classes, this corresponds to the standard numerical or lexicographic ordering.
For numeric types (Integer
, Double
, etc.), it imposes ascending numerical order.
For characters (Character
), it imposes the Unicode order.
For strings (String
), it imposes lexicographic (dictionary) order.
Comparator.reverseOrder()
: Returns a comparator that imposes the reverse of the natural ordering.
nullsFirst(Comparator<T> comparator)
and nullsLast(Comparator<T> comparator)
:
Comparator.nullsFirst()
: Returns a comparator that considers null values to be less than non-null values, using the specified comparator for non-null values. This means that when you use this comparator to sort a list, null values will appear at the beginning of the sorted list.Comparator.nullsLast()
: Returns a comparator that considers null values to be greater than non-null values, using the specified comparator for non-null values. This means that when you use this comparator to sort a list, null values will appear at the end of the sorted list.
comparing(Function<? super T, ? extends U> keyExtractor)
:
- Returns a comparator that compares objects based on a key extracted by the provided function.
Comparator<String> byLength = Comparator.comparing(String::length);
comparingInt(ToIntFunction<? super T> keyExtractor)
, comparingLong(ToLongFunction<? super T> keyExtractor)
, and comparingDouble(ToDoubleFunction<? super T> keyExtractor)
:
Provide specialized comparators for primitive data types
Now, let’s begin with the problems.
- Sort the strings based on their length in ascending order.
2. Sort the list of integers in descending order and print the result.
3. Sort the list of employees based on their age in ascending order and print the result.
4. Sort the list of employees based on their age in ascending order. If the ages are the same, compare by salary. Print the result.
5. Sort the list of strings based on the index of the first occurrence of “e” in each string and print the result.
6. Sort a list of strings, ignoring case sensitivity, using a case-insensitive comparator.
7. Sort a list of dates in ascending order using the comparing() method with a lambda expression.
8. Sort a list of strings, placing null values at the end.
9. Sort a list of students first by grade in ascending order and then by age in descending order.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.