1. 概述

在日常开发中,比较多个数值并找出最大值是一个非常常见的需求。

本文将探讨如何在 Kotlin 中找出三个数中的最大值,并进一步扩展到从任意 n 个数中找出最大值的通用解法。

我们会从手写算法开始,逐步过渡到使用标准库函数,帮助你理解背后的逻辑和性能差异,避免踩坑。


2. 问题引入

从三个或更多数字中找出最大值本身并不是一个复杂的问题。Kotlin 标准库已经提供了现成的便捷方法。

但我们先不急着用轮子,而是✅从零实现自己的解决方案,顺便熟悉一些 Kotlin 的优雅语法特性——这对刚接触 Kotlin 的开发者尤其有帮助。

本文以 Int 类型为例,但所有方案均可适配其他 Number 子类型(如 LongDouble 等)。

接下来,直接上代码。


3. 手动实现解决方案

3.1 使用 if-else 表达式

最直观的思路是:逐个判断每个数是否大于等于另外两个数。若前两个都不是最大值,则第三个必然是答案。

val a = 42
val b = 100
val c = -42
val result = if (a >= b && a >= c) {
    a
} else if (b >= a && b >= c) {
    b
} else {
    c
}
assertEquals(100, result)

⚠️ 注意:Kotlin 中的 if表达式(expression),可以返回值,因此可以直接赋值给变量。这是和 Java 的关键区别之一。

3.2 使用 when 表达式优化可读性

同样的逻辑,改用 when 表达式会让代码更清晰:

val (a, b, c) = listOf(42, 100, -42)
val result = when {
    a >= b && a >= c -> a
    b >= a && b >= c -> b
    else -> c
}
assertEquals(100, result)

这里还用到了 Kotlin 的解构声明(destructuring declaration),一行代码初始化三个变量,简洁又高效。

时间复杂度分析 ❌

该算法最坏情况下需要进行 4 次比较(每数两次)。推广到 n 个数时,若采用类似两两对比的方式,比较次数可达 (n-1)²,时间复杂度为 O(n²) —— 显然不适合大规模数据。

3.3 优化算法:链式比较 ✅

更好的思路是:先比较前两个数得出较大者,再与第三个数比较。只需 2 次比较即可得出结果。

推广到 n 个数时,只需遍历一次,时间复杂度为 **O(n)**。

实现如下:

val (a, b, c) = listOf(42, 100, -42)
val maxOfAB = if (a >= b) a else b
val result = if (c >= maxOfAB) c else maxOfAB
assertEquals(100, result)

这个模式简单高效,适合手动实现且易于理解。


4. 使用 math.max() 方法

Kotlin 提供了 kotlin.math.max(a, b) 函数,用于返回两个数中的较大值。

我们可以嵌套调用两次,轻松解决三数取最大:

val (a, b, c) = listOf(42, 100, -42)
val result = max(max(a, b), c)
assertEquals(100, result)

✅ 优点:代码极简,语义清晰
⚠️ 缺点:无法直接处理空值或集合;对于更多数字需多次嵌套,不够灵活

📌 提示:max() 来自 kotlin.math 包,需确保导入正确包路径


5. 处理 n 个数的情况

实际开发中,我们面对的往往是集合形式的数据(如 List<Int>)。幸运的是,Kotlin 集合 API 提供了原生支持。

5.1 使用 max()

直接调用 max() 即可获取集合中的最大值:

val nNumbers = listOf(42, 100, -42, 20, 43, -2, 103, 420)
val result = nNumbers.max()
assertEquals(420, result)

❌ 踩坑警告:如果列表为空,max() 会抛出 NoSuchElementException

assertThrows<NoSuchElementException> { emptyList<Int>().max() }

这在生产环境中极易引发运行时异常,务必小心。

5.2 推荐方案:使用 maxOrNull()

为了安全起见,当集合可能为空时,应使用 maxOrNull()

val possibleMax = emptyList<Int>().maxOrNull()
assertNull(possibleMax)

✅ 返回 Int? 类型,空集合返回 null,避免崩溃,更适合业务逻辑处理。

方法 是否允许空集合 返回类型 建议场景
max() ❌ 抛异常 Int 确保非空时使用
maxOrNull() ✅ 返回 null Int? 通用推荐,更安全

6. 总结

本文我们实现了两种找最大值的手动算法:

  • 基于多重条件判断(O(n²))
  • 链式比较法(O(n)),更高效

随后介绍了 Kotlin 标准库中的实用方法:

  • kotlin.math.max(a, b):适用于固定两个数的比较
  • Collection.max()maxOrNull():处理集合数据的首选,后者更安全

📌 最佳实践建议:

  • 小范围比较可用 max(max(a,b), c)
  • 集合操作优先使用 maxOrNull() 防止 NPE
  • 理解底层逻辑才能写出健壮代码,别盲目依赖 API

完整示例代码已托管至 GitHub:https://github.com/Baeldung/kotlin-tutorials/tree/master/kotlin-math


原始标题:Finding the Largest Among Three Numbers in Kotlin