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

Kotlin ArrayList排序不符合预期,请求分析问题原因

问题分析:为何foodList未按预期排序?

原始代码与需求

数据类及列表定义:

data class Food(val name: String)

val addedFoodList = arrayListOf(
    Food(name = "Avocado Oil")
)

val foodList = arrayListOf(
    Food(name = "Avocado"),
    Food(name = "Avocado Second"),
    Food(name = "Avocado Third"),
    Food(name = "Avocado Oil"),
)

需求:将foodList中与addedFoodList同名的食物移至列表首位。

你的排序实现

fun getSortedFoodList(foodList: ArrayList<Food>): List<Food> {
    val sortedFoodList = foodList.sortedBy { food ->
        val foundFood = mockAddedFood.find { addedFood -> 
             food.name == addedFood.name
        }
        
        val indexOf = mockAddedFood.indexOf(foundFood)
        
        return@sortedBy indexOf
    }
    
    return sortedFoodList
}

结果对比

  • 实际结果:[Food(name=Avocado), Food(name=Avocado Second), Food(name=Avocado Third), Food(name=Avocado Oil)]
  • 预期结果:[Food(name=Avocado Oil), Food(name=Avocado), Food(name=Avocado Second), Food(name=Avocado Third)]

问题原因

你用sortedBy时的排序key逻辑完全搞反了:

  • 当食物在addedFoodList中匹配成功时,foundFood是有效元素,indexOf返回0
  • 当匹配失败时,foundFood为null,mockAddedFood.indexOf(null)返回-1
  • sortedBy是升序排序,-1比0小,所以key为-1的未匹配项会排在key为0的匹配项前面,最终结果和预期相反。

修复方案

方案1:调整排序key优先级

给匹配项设置更小的key值,让它们排在前面:

fun getSortedFoodList(foodList: ArrayList<Food>): List<Food> {
    return foodList.sortedBy { food ->
        // 匹配到的返回0,未匹配的返回1,升序后匹配项自然在前
        if (addedFoodList.any { it.name == food.name }) 0 else 1
    }
}

方案2:更高效的分组处理(避免重复遍历)

先拆分匹配项与非匹配项,再合并,查询效率更高:

fun getSortedFoodList(foodList: ArrayList<Food>): List<Food> {
    val addedNames = addedFoodList.map { it.name }.toSet() // 转Set将查询复杂度降为O(1)
    val matched = foodList.filter { it.name in addedNames }
    val unmatched = foodList.filter { it.name !in addedNames }
    return matched + unmatched
}

内容的提问来源于stack exchange,提问作者Aris Paskalov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:24:29