1. Overview
A common task in software development is needing to find the maximum value within a given array.
In this tutorial, we’ll see some techniques to get the maximum value in arrays with Kotlin.
2. Max Built-in Methods
Arrays in Kotlin support a built-in method that retrieves the max value or null when the array is empty:
val array = listOf(5, 6, 7, 8, 9, 4, 3, 2, 1)
val maxOrNull = array.maxOrNull()
Older versions of Kotlin featured a max() function that behaved like the current maxOrNull(). Some versions even removed the max() function until Kotlin 1.7 reintroduced it with a non-nullable return type. The current version now returns the array element or throws an exception for empty cases:
assertThatExceptionOfType(NoSuchElementException::class.java).isThrownBy {
val array = emptyArray<Int>()
val max = array.max()
}
3. Max With Custom Selector
If we want to use a custom function selector or retrieve the max value by a specific field on a data class, Kotlin provides two versions — maxBy(), which throws an exception if the Array is empty, or maxByOrNull(), which returns null for empty arrays:
val array = listOf(Person("Alan",34), Person("Jason",45), Person("Joe",28))
val maxOrNull: Int? = array.maxByOrNull { p -> p.age }
val max: Int = array.maxBy { p -> p.age }
The same result can be obtained by sorting the array in descending order by the desired field and getting the first element within the sorted array:
val array = listOf(Person("Alan", 34), Person("Jason", 45), Person("Joe", 28))
val max = array.sortedByDescending { p -> p.age }.first()
4. Max With Custom Comparator
There are cases when we want to specify a comparison rule to calculate the max value. In Kotlin, the method maxWith() allows defining the comparator to use in the rule evaluation process. Similarly to the previous examples, this function throws an exception for empty arrays. There’s a variant maxWithOrNull() that handles empty arrays with null results:
val array = listOf(
Person("Alan", 34, Height(5, 10)),
Person("Jason", 45, Height(5, 11)),
Person("Joe", 28, Height(5, 9))
)
val maxOrNull = array.maxWithOrNull(compareBy({ it.height.feet }, { it.height.inches }))
val max = array.maxWith(compareBy({ it.height.feet }, { it.height.inches }))
Deciding between maxBy() and maxWith() will depend on the implementation logic. If the elements can only be sorted by comparing, then maxWith() might be needed. The most obvious example is when we need to select an element by more than one attribute.
There may be cases where more than one element is the maximum within the array. For those cases, the first matching element defined in the array will be returned:
val array = listOf(
Person("Alan", 34, Height(5, 10)),
Person("Jason", 45, Height(5, 11)),
Person("Joe", 45, Height(5, 11))
)
val max = array.maxWith(compareBy({ it.height.feet }, { it.height.inches }))
assertThat(max).isNotNull()
assertThat(max.name).isEqualTo("Jason")
5. Conclusion
In this tutorial, we’ve explored some techniques to retrieve the maximum value within an array using built-in methods in Kotlin.
As always, the complete code for this article is available over on GitHub.