Kotlin Tutoial
Basics
Control Flow
Array & String
Functions
Collections
OOPs Concept
Exception Handling
Null Safety
Regex & Ranges
Java Interoperability
Miscellaneous
Android
In Kotlin, the Comparator
interface is used to order a collection of objects that are not inherently comparable. The interface provides a method compare(a: T, b: T)
which returns:
a
is less than b
.a
is equal to b
.a
is greater than b
.In this tutorial, we'll go through the basics of creating and using comparators in Kotlin.
1. Basic Comparator:
To create a comparator for a data class Person
that compares persons based on their age:
data class Person(val name: String, val age: Int) val ageComparator = Comparator<Person> { p1, p2 -> p1.age - p2.age }
2. Using the Comparator:
Suppose we have a list of Person
objects:
val people = listOf( Person("Alice", 30), Person("Bob", 25), Person("Charlie", 29) ) val sortedByAge = people.sortedWith(ageComparator) println(sortedByAge)
3. Chained Comparators:
Kotlin's Comparator
interface provides the thenBy
and thenComparing
extensions for chaining comparators:
val nameComparator = Comparator<Person> { p1, p2 -> p1.name.compareTo(p2.name) } val combinedComparator = ageComparator.thenBy(nameComparator)
With the above combinedComparator
, the list is first sorted by age, and then by name for those with the same age.
4. Natural Ordering:
If the class implements the Comparable
interface, you can use compareBy
to build comparators:
data class Product(val name: String, val price: Double) : Comparable<Product> { override fun compareTo(other: Product) = price.compareTo(other.price) } val products = listOf( Product("Shirt", 29.99), Product("Shoe", 49.99), Product("Hat", 19.99) ) val sortedProducts = products.sortedWith(compareBy { it.name }) println(sortedProducts)
5. Reverse Ordering:
You can reverse the order of a comparator using reversed()
:
val descendingAgeComparator = ageComparator.reversed()
6. Null Handling:
Kotlin provides nullsFirst
and nullsLast
to handle cases where the collection might have null values:
val listWithNulls = listOf(null, Person("Dave", 40), null, Person("Eve", 35)) val sortedList = listWithNulls.sortedWith(nullsFirst(ageComparator)) println(sortedList)
Conclusion: Using comparators in Kotlin is straightforward thanks to the various extensions and utilities provided by the standard library. They are powerful tools for custom sorting, allowing for chained, reversed, and null-handling orders. Familiarity with comparators can significantly enhance your data processing capabilities in Kotlin.
Description: A simple example of using a comparator in Kotlin to sort a list of strings.
Code:
fun main() { val fruits = listOf("Apple", "Banana", "Orange", "Mango") val comparator = Comparator { fruit1: String, fruit2: String -> fruit1.compareTo(fruit2) } val sortedFruits = fruits.sortedWith(comparator) println("Sorted Fruits: $sortedFruits") }
Description: Sorting a list of custom objects using a comparator in Kotlin.
Code:
data class Person(val name: String, val age: Int) fun main() { val people = listOf(Person("Alice", 25), Person("Bob", 30), Person("Charlie", 22)) val comparator = Comparator { person1: Person, person2: Person -> person1.age.compareTo(person2.age) } val sortedPeople = people.sortedWith(comparator) println("Sorted People by Age: $sortedPeople") }
Description: Implementing a custom comparator for sorting custom objects in Kotlin.
Code:
data class Student(val name: String, val grade: Int) class GradeComparator : Comparator<Student> { override fun compare(student1: Student, student2: Student): Int { return student1.grade.compareTo(student2.grade) } } fun main() { val students = listOf(Student("Alice", 85), Student("Bob", 92), Student("Charlie", 78)) val gradeComparator = GradeComparator() val sortedStudents = students.sortedWith(gradeComparator) println("Sorted Students by Grade: $sortedStudents") }
Description: Comparing custom objects using a comparator in Kotlin.
Code:
data class Animal(val name: String, val legs: Int) fun main() { val animals = listOf(Animal("Dog", 4), Animal("Spider", 8), Animal("Bird", 2)) val comparator = Comparator { animal1: Animal, animal2: Animal -> animal1.legs.compareTo(animal2.legs) } val sortedAnimals = animals.sortedWith(comparator) println("Sorted Animals by Legs: $sortedAnimals") }
Description: Sorting a list of objects based on multiple criteria using a comparator in Kotlin.
Code:
data class Product(val name: String, val price: Double, val rating: Double) fun main() { val products = listOf( Product("Laptop", 1200.0, 4.5), Product("Phone", 800.0, 4.2), Product("Tablet", 500.0, 4.0) ) val comparator = compareBy<Product> { it.rating }.thenBy { it.price } val sortedProducts = products.sortedWith(comparator) println("Sorted Products: $sortedProducts") }
Description: Understanding the difference between using a comparator and making objects comparable in Kotlin.
Code:
data class Person(val name: String, val age: Int) : Comparable<Person> { override fun compareTo(other: Person): Int { return this.age.compareTo(other.age) } } fun main() { val people = listOf(Person("Alice", 25), Person("Bob", 30), Person("Charlie", 22)) // Using Comparable val sortedPeopleComparable = people.sorted() // Using Comparator val comparator = compareBy<Person> { it.age } val sortedPeopleComparator = people.sortedWith(comparator) println("Sorted People (Comparable): $sortedPeopleComparable") println("Sorted People (Comparator): $sortedPeopleComparator") }
Description: Sorting a list of objects in descending order using a comparator in Kotlin.
Code:
data class Book(val title: String, val author: String, val publicationYear: Int) fun main() { val books = listOf( Book("Book1", "Author1", 2000), Book("Book2", "Author2", 1995), Book("Book3", "Author3", 2020) ) val comparator = compareByDescending<Book> { it.publicationYear } val sortedBooks = books.sortedWith(comparator) println("Sorted Books (Descending Order): $sortedBooks") }
Description: Sorting a list of custom objects using a comparator with a custom sorting logic in Kotlin.
Code:
data class Employee(val name: String, val salary: Double) fun main() { val employees = listOf( Employee("Alice", 50000.0), Employee("Bob", 60000.0), Employee("Charlie", 45000.0) ) val comparator = Comparator { employee1: Employee, employee2: Employee -> employee1.salary.compareTo(employee2.salary) } val sortedEmployees = employees.sortedWith(comparator) println("Sorted Employees by Salary: $sortedEmployees") }
Description: Chaining comparators to achieve complex sorting logic in Kotlin.
Code:
data class Student(val name: String, val grade: Int, val age: Int) fun main() { val students = listOf( Student("Alice", 90, 21), Student("Bob", 85, 22), Student("Charlie", 90, 20) ) val comparator = compareBy<Student> { it.grade }.thenBy { it.age } val sortedStudents = students.sortedWith(comparator) println("Sorted Students: $sortedStudents") }