kotlin-sort-list-objects-feature-image

Kotlin – Sort List of custom Objects

In this tutorial, I will show you several useful ways to sort List of custom Objects for Ascending and Descending order in Kotlin. You’re gonna know how to:

  • sort List of Objects by one field or multiple fields
  • use your custom Comparator to sort List of Objects
  • implement Comparable interface to make sorting List of Objects more convenient

Related Posts:
Kotlin List & Mutable List tutorial with examples
Kotlin – Compare Objects with Comparable Example


Sort List of custom Objects by field in Kotlin

sortBy

We can sort a List of Objects by one field by using sortBy(): sortBy {it.field}

For example, if we have Date class like this:

package com.bezkoder.kotlin.sortlist

data class Date(val year: Int, val month: Int, val day: Int) {
}

This is how we sort List of Date objects by field year

package com.bezkoder.kotlin.sortlist

fun main(args: Array<String>) {
	val dates = mutableListOf(
		Date(2020, 4, 3),
		Date(2021, 5, 16),
		Date(2020, 1, 29)
	)
	
	println("--- ASC ---")	
	dates.sortBy { it.year }
	dates.forEach { println(it) }
}

The result:

--- ASC ---
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)
Date(year=2021, month=5, day=16)

sortBy Descending

You can use sortByDescending {it.field} for descending order.

println("--- DESC ---")
dates.sortByDescending { it.year }
dates.forEach { println(it) }

The result:

--- DESC ---
Date(year=2021, month=5, day=16)
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)

sortedBy

If you don’t want to change the original List, you can use sortedBy() method that return another sorted List.

/* dates
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)
Date(year=2020, month=1, day=29) */

println("--- ASC ---")
val sortedDates = dates.sortedBy { it.year }
dates.forEach { println(it) }
println("------")
sortedDates.forEach { println(it) }

The result:

--- ASC ---
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)
Date(year=2020, month=1, day=29)
------
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)
Date(year=2021, month=5, day=16)

sortedBy Descending

And sortedByDescending() for descending order.

println("--- DESC ---")
val sortedDatesDescending = dates.sortedByDescending { it.year }
dates.forEach { println(it) }
println("------")
sortedDatesDescending.forEach { println(it) }

The result:

--- DESC ---
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)
Date(year=2020, month=1, day=29)
------
Date(year=2021, month=5, day=16)
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)

With sortBy() & sortedByDescending(), you can see that we are able to sort by ONLY ONE field – year.

How about continue sorting by month and day fields? We have sortWith() method.

Sort List by multiple fields in Kotlin

sortWith

We can sort a List of Objects by multiple fields passing a Comparator object to sortWith() method.

The Comparator object is created by using compareBy() and thenBy() method.

val dates = mutableListOf(
	Date(2020, 4, 3),
	Date(2021, 5, 16),
	Date(2020, 1, 29)
)

println("--- ASC ---")
dates.sortWith(compareBy<Date> { it.year }.thenBy { it.month }.thenBy { it.day })
dates.forEach { println(it) }

Now, check the result, you will see that if years are equal, the program will continue to compare month, then day.

--- ASC ---
Date(year=2020, month=1, day=29)
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)

sortWith Descending

If you want to sort for descending order, just put additional method of Comparator named reverse().

For example:

println("--- DESC ---")
dates.sortWith(compareBy<Date> { it.year }.thenBy { it.month }.thenBy { it.day })
dates.reverse()
dates.forEach { println(it) }

The result:

--- DESC ---
Date(year=2021, month=5, day=16)
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)

sortedWith

sortedWith() returns a sorted List but doesn’t change the original List. We continue to pass Comparator object to the method.

val dates = mutableListOf(
	Date(2020, 4, 3),
	Date(2021, 5, 16),
	Date(2020, 1, 29)
)

println("--- ASC ---")
val sortedDates = dates.sortedWith(compareBy<Date> { it.year }.thenBy { it.month }.thenBy { it.day })
dates.forEach { println(it) }
println("------")
sortedDates.forEach { println(it) }

In the result, dates was not changed.

--- ASC ---
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)
Date(year=2020, month=1, day=29)
------
Date(year=2020, month=1, day=29)
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)

sortedWith Descending

For descending order, just put additional method named reversed().

For example:

println("--- DESC ---")
val sortedDatesDescending =
	dates.sortedWith(compareBy<Date> { it.year }.thenBy { it.month }.thenBy { it.day }).reversed()
dates.forEach { println(it) }
println("------")
sortedDatesDescending.forEach { println(it) }

Check the result in console-

--- DESC ---
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)
Date(year=2020, month=1, day=29)
------
Date(year=2021, month=5, day=16)
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)

Kotlin Sort List of Objects with custom Comparator

Overview

We’re gonna follow these steps:
– Implement Comparator interface for the class that you use for handling sorting.
– Override compare(object1: T, object2: T) method and:

  • return zero if object1 is equal object2
  • a negative number if object1 is less than object2
  • a positive number if object1 is greater than object2

– Use sortedWith(comparator: Comparator) method that returns a List.

Create Class for objects to be sorted

We’re gonna create a data class with 3 fields: year, month & day.

Date.kt

package com.bezkoder.kotlin.sortlist

data class Date(val year: Int, val month: Int, val day: Int) {
}

Create Class for handling sorting

This is the main part, CompareDates class overrides Comparator.compare() method.

CompareDates.kt

package com.bezkoder.kotlin.sortlist

class CompareDates {

	companion object : Comparator<Date> {

		override fun compare(a: Date, b: Date): Int = when {
			a.year != b.year -> a.year - b.year
			a.month != b.month -> a.month - b.month
			else -> a.day - b.day
		}
	}
}

Check the result

Now we can sort the List easily by using sortedWith(CompareDates).

app.kt

package com.bezkoder.kotlin.sortlist

fun main(args: Array<String>) {
	val dates = mutableListOf(
		Date(2020, 4, 3),
		Date(2021, 5, 16),
		Date(2020, 1, 29)
	)

	println("--- ASC ---")
	dates.sortedWith(CompareDates).forEach { println(it) }

	println("--- DESC ---")
	dates.sortedWith(CompareDates).reversed().forEach { println(it) }
}

The result in console will look like this-

--- ASC ---
Date(year=2020, month=1, day=29)
Date(year=2020, month=4, day=3)
Date(year=2021, month=5, day=16)
--- DESC ---
Date(year=2021, month=5, day=16)
Date(year=2020, month=4, day=3)
Date(year=2020, month=1, day=29)

Sort List of custom Objects with Kotlin Comparable

Overview

We’re gonna follow these steps:
– Implement Comparable interface for the class of objects you want to sort.
– Override compareTo(other: T) method and:

  • return zero if this object is equal other
  • a negative number if the object is less than other
  • a positive number if it is greater than other

– Use sorted() method that returns a List.

Create Comparable Class

Let’s create a class that implements Comparable.

MyComparableDate.kt

package com.bezkoder.kotlin.sortlist

import kotlin.Comparable

data class MyComparableDate(val year: Int, val month: Int, val day: Int) : Comparable {

	override fun compareTo(other: MyComparableDate) = when {
		year != other.year -> year - other.year
		month != other.month -> month - other.month
		else -> day - other.day
	}
}

Check the result

Our work becomes simple now, we just need to use sorted() method for ascending order or sortedDescending() for descending order.

app.kt

package com.bezkoder.kotlin.sortlist

fun main(args: Array<String>) {
	val myComparableDates = listOf(
		MyComparableDate(2021, 4, 3),
		MyComparableDate(2020, 7, 29),
		MyComparableDate(2021, 2, 26)
	)

	println("--- ASC ---")
	myComparableDates.sorted().forEach { println(it) }

	println("--- DESC ---")
	myComparableDates.sortedDescending().forEach { println(it) }
}

You can see the result in console.

--- ASC ---
MyComparableDate(year=2020, month=7, day=29)
MyComparableDate(year=2021, month=2, day=26)
MyComparableDate(year=2021, month=4, day=3)
--- DESC ---
MyComparableDate(year=2021, month=4, day=3)
MyComparableDate(year=2021, month=2, day=26)
MyComparableDate(year=2020, month=7, day=29)

Conclusion

Today we’ve learned many ways to sort a List of custom Objects in Kotlin, from simple to more complicated way. You’ve known how to sort by field and multiple fields, or by using Comparator/Comparable.

Happly Learning! See you again.

Further Reading

5 thoughts to “Kotlin – Sort List of custom Objects”

  1. Thanks in advance! This is a complete reference for Sorting List in Kotlin. I’m looking forward to your Kotlin filter List tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *