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
相关产品推荐
相关产品推荐

