Kotlin使用Map过滤对象列表触发空指针异常的问题排查
问题原因
原有实现存在3个核心问题,导致异常和逻辑不符合预期:
- 未跳过不匹配过滤规则的参数:使用
associate会强制为列表中每一个参数生成键值对,当参数名不匹配任何过滤规则时,filters.filter{...}返回空集合,调用keys.first()会直接抛出元素不存在异常 - 匹配逻辑错误:仅判断别名集合的第一个元素(
it.value.first()),无法匹配同分类下的其他别名,例如示例中producer别名永远不会被命中 - 空安全缺失:使用
!!强制对param.values做非空断言,遇到values为null或空列表的参数时,会直接抛出空指针或越界异常
修正后代码
fun filterParameters( parametersList: List<Parameter>, filters: Map<ParameterName, Set<String>> ): Map<String, ParameterValue> { // 预构建别名到主分类键的映射,提升匹配效率 val aliasMap = mutableMapOf<String, String>() filters.forEach { (paramName, aliasSet) -> aliasSet.forEach { alias -> aliasMap[alias.lowercase()] = paramName.key } } return buildMap { parametersList.forEach paramLoop@{ param -> // 空值直接跳过 val currentName = param.name?.lowercase() ?: return@paramLoop val currentValues = param.values ?: return@paramLoop if (currentValues.isEmpty()) return@paramLoop // 未匹配到分类的参数直接跳过 val mainKey = aliasMap[currentName] ?: return@paramLoop // 同一分类已存在匹配项时不覆盖,需要后匹配项覆盖的话替换为put即可 putIfAbsent(mainKey, ParameterValue(value = currentValues.first())) } } }
实现说明
- 预构建别名映射后,参数匹配无需每次遍历全量过滤规则,匹配效率更高,同时支持同一分类下多别名的匹配逻辑
- 全程使用Kotlin空安全语法,无强制非空断言,避免空指针异常
- 无效参数、不匹配规则的参数直接跳过,不会触发集合空取首元素的异常
- 传入示例入参执行后,返回结果为
{Manufacturer=ParameterValue(parameterId=null, value=Nike, valueId=null)},完全符合预期输出要求。
内容的提问来源于stack exchange,提问作者xard4sTR
相关产品推荐
相关产品推荐

