Kotlin Map映射转换

Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、mapValues、flatten、flatMap

引言

在之前的主题中,我们学习了如何筛选(filter)排序(sort)集合。然而,处理集合时最重要的任务之一是转换集合中的元素。本主题将教你如何使用 Kotlin 的转换函数将一个集合转换为另一个集合。


映射(Mapping)

map()
  • 用于将集合中的每个元素应用一个转换函数,返回一个新集合

  • 一对一转换:每个原始元素都对应一个转换后的元素。

示例:
val numbers = listOf(1, 2, 3)
println(numbers.map { it * 2 }) // [2, 4, 6]
mapIndexed()
  • map() 类似,但提供元素的 索引 作为额外参数。
val words = listOf("anne", "michael", "caroline")
println(words.mapIndexed { index, value ->
    if (index % 2 == 0) value.uppercase() else value
}) // [ANNE, michael, CAROLINE]
应用场景
  • 获取每个字符串长度:words.map { it.length }

  • 将字符串转为整数:listOf("1", "2", "3").map { it.toInt() }

  • 首字母大写:words.map { it.capitalize() }

  • 转换 Map 的键或值


可空类型的映射(Mapping with nullables)

如果某些元素无法转换,map() 会返回 null,集合变成 List<T?>。为避免 null,使用:

mapNotNull() / mapIndexedNotNull()
  • 自动过滤掉为 null 的结果,使结果为非空集合(List<T>)。
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.map { if (it % 2 == 0) it else null }) // [null, 2, null, 4, null]
println(numbers.mapNotNull { if (it % 2 == 0) it else null }) // [2, 4]

映射 Map 类型(Map Mapping)

Kotlin 的 Map 类型可以使用以下两种方法转换:

mapKeys()
  • 转换 Map 的 键
mapValues()
  • 转换 Map 的 值
val map = mapOf(1 to "one", 2 to "two")
println(map.mapKeys { it.key * 2 }) // {2=one, 4=two}
println(map.mapValues { it.value.uppercase() }) // {1=ONE, 2=TWO}

Flatten(扁平化)

flatten()
  • 把嵌套集合(List of Lists)展开成一个单一列表。
val nested = listOf(listOf(1,2), listOf(3,4))
println(nested.flatten()) // [1, 2, 3, 4]
flatMap()
  • map,再 flatten,适用于一对多转换
val nested = listOf(listOf(1,2), listOf(3,4))
println(nested.flatMap { it.map { it * 2 } }) // [2, 4, 6, 8]
  • 也可以用于 List<Map>
val listOfMaps = listOf(mapOf(1 to "one"), mapOf(2 to "two"))
val result = listOfMaps.flatMap { it.entries }.associate { it.toPair() }
println(result) // {1=one, 2=two}

总结(Conclusion)

我们学到了多种转换集合的方式:

功能方法
一对一转换map()
一对一+索引mapIndexed()
过滤 null 结果mapNotNull()
Map 键值转换mapKeys() / mapValues()
多对一flatten()
一对多flatMap()
### Kotlin 实体类之间转换的方法 在 Kotlin 中实现实体类之间的转换可以通过多种方式完成,这里展示一种常见的方式——通过构造函数或工厂方法来进行转换。假设存在两个实体类 `Person` 和 `Employee`,其中 `Employee` 继承自 `Person` 并添加了一些额外的信息。 #### 定义原始实体类 ```kotlin data class Person( val id: Int, val name: String, val age: Int ) ``` #### 定义目标实体类 ```kotlin data class Employee( val employeeId: Int, val department: String, val position: String, val personInfo: Person // 包含基础个人信息 ) ``` 为了方便地从 `Person` 创建 `Employee` 对象,可以在 `Employee` 类内部定义一个伴生对象中的静态方法作为工厂模式的一部分: ```kotlin companion object { fun from(person: Person, dept: String, pos: String): Employee { return Employee(employeeId = generateUniqueID(), department = dept, position = pos, personInfo = person) } private var lastId = 0 private fun generateUniqueID(): Int { lastId++ return lastId } } ``` 这样就可以很容易地创建一个新的 `Employee` 实例而不需要重复输入所有的字段信息[^1]。 当需要将多个不同类型的实体互相转换时,还可以考虑使用映射库如 MapStruct 或者编写通用的转换接口和服务来处理更复杂的场景[^2]。 对于简单的属性复制任务来说,在某些情况下也可以利用反射机制或是第三方框架(例如 ModelMapper),但是这些方案通常会带来一定的性能开销以及潜在的安全风险,所以在实际项目中应当谨慎评估后再决定是否采用[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值