You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中简化复杂的分类判断逻辑?

优化后的简洁实现方案

方案1:直接内联定义规则列表

省去冗余的单独函数,直接把所有分类规则集中定义在列表中,代码更紧凑直观:

class Abc {
    private val categoryRules by lazy {
        listOf(
            Item("Low") { itemOne, itemTwo -> itemOne < 90 && itemTwo < 60 },
            Item("Normal") { itemOne, itemTwo -> itemOne in 90..119 && itemTwo in 60..80 },
            Item("Elevated") { itemOne, itemTwo -> itemOne in 120..129 && itemTwo < 80 },
            Item("High") { itemOne, itemTwo -> itemOne in 130..139 || itemTwo in 80..89 },
            Item("Very high") { itemOne, itemTwo -> itemOne in 140..179 || itemTwo in 90..119 },
            Item("Extremely High") { itemOne, itemTwo -> itemOne >= 180 || itemTwo >= 120 }
        )
    }

    fun getItem(itemOne: Int, itemTwo: Int): Item {
        return categoryRules.firstOrNull { it.condition(itemOne, itemTwo) } 
            ?: Item("Default") { _, _ -> false }
    }
}

data class Item(
    val itemName: String,
    val condition: (Int, Int) -> Boolean,
)

方案2:用数据类封装阈值规则(更利于测试)

把每个分类的阈值逻辑抽成结构化的数据类,规则更清晰,单独测试和修改都更方便:

// 封装分类阈值规则,明确每个维度的限制条件
data class CategoryThreshold(
    val name: String,
    val itemOneRange: ClosedRange<Int>? = null,
    val itemOneLowerThan: Int? = null,
    val itemOneGreaterOrEqual: Int? = null,
    val itemTwoRange: ClosedRange<Int>? = null,
    val itemTwoLowerThan: Int? = null,
    val itemTwoGreaterOrEqual: Int? = null,
    val logic: Logic = Logic.AND // 多条件的逻辑关系:AND/OR
)

enum class Logic { AND, OR }

class Abc {
    private val categoryThresholds by lazy {
        listOf(
            CategoryThreshold(
                name = "Low",
                itemOneLowerThan = 90,
                itemTwoLowerThan = 60
            ),
            CategoryThreshold(
                name = "Normal",
                itemOneRange = 90..119,
                itemTwoRange = 60..80
            ),
            CategoryThreshold(
                name = "Elevated",
                itemOneRange = 120..129,
                itemTwoLowerThan = 80
            ),
            CategoryThreshold(
                name = "High",
                itemOneRange = 130..139,
                itemTwoRange = 80..89,
                logic = Logic.OR
            ),
            CategoryThreshold(
                name = "Very high",
                itemOneRange = 140..179,
                itemTwoRange = 90..119,
                logic = Logic.OR
            ),
            CategoryThreshold(
                name = "Extremely High",
                itemOneGreaterOrEqual = 180,
                itemTwoGreaterOrEqual = 120,
                logic = Logic.OR
            )
        )
    }

    fun getItem(itemOne: Int, itemTwo: Int): Item {
        val matchedThreshold = categoryThresholds.firstOrNull { threshold ->
            val itemOneMatch = when {
                threshold.itemOneRange != null -> itemOne in threshold.itemOneRange
                threshold.itemOneLowerThan != null -> itemOne < threshold.itemOneLowerThan
                threshold.itemOneGreaterOrEqual != null -> itemOne >= threshold.itemOneGreaterOrEqual
                else -> true // 无限制则默认匹配
            }
            val itemTwoMatch = when {
                threshold.itemTwoRange != null -> itemTwo in threshold.itemTwoRange
                threshold.itemTwoLowerThan != null -> itemTwo < threshold.itemTwoLowerThan
                threshold.itemTwoGreaterOrEqual != null -> itemTwo >= threshold.itemTwoGreaterOrEqual
                else -> true
            }
            when (threshold.logic) {
                Logic.AND -> itemOneMatch && itemTwoMatch
                Logic.OR -> itemOneMatch || itemTwoMatch
            }
        }
        return matchedThreshold?.let { Item(it.name) { _, _ -> true } } 
            ?: Item("Default") { _, _ -> false }
    }
}

data class Item(
    val itemName: String,
    val condition: (Int, Int) -> Boolean,
)

优化说明

  • 减少冗余:方案1省去了6个重复的getXxxItem函数,代码结构更紧凑。
  • 简化查找逻辑:用Kotlin标准库的firstOrNull替代手动循环,代码更简洁可靠。
  • 提升可测试性:方案2把阈值规则结构化,测试时可以单独验证每个阈值的正确性,修改规则也无需改动lambda逻辑。
  • IntRange覆盖性:你所有的条件都可以用IntRange配合简单比较运算符实现,完全覆盖原有逻辑,比如itemOne < 90等价于itemOne in Int.MIN_VALUE..89,直接用<更直观。

内容的提问来源于stack exchange,提问作者Compose Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 01:07:35