导读大纲
-
- [1.1 在 Kotlin 中创建集合](#1.1 在 Kotlin 中创建集合)
- [1.2 自定义 joinToString 函数来实现字符串打印](#1.2 自定义 joinToString 函数来实现字符串打印)
1.1 在 Kotlin 中创建集合
- 学习如何创建集合
- 使用setOf函数创建集合, 使用mapOf创建映射, 使用listOf创建列表
- <1> to 并不是一个特殊的结构体 , 而是一个普通函数
- infix修饰符 表示这是一个中缀函数 ,Kotlin语言的又一大特性
- infix修饰符 表示这是一个中缀函数 ,Kotlin语言的又一大特性
- <2> javaClass 相当于 Java 的 getClass()
kotlin
fun main() {
val set = setOf(1, 7, 53)
val list = listOf(1, 7, 53)
val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three") // <1>
println(set.javaClass) // <2>
// class java.util.LinkedHashSet
println(list.javaClass)
// class java.util.Arrays$ArrayList
println(map.javaClass)
// class java.util.LinkedHashMap
}
-
正如所看到的,Kotlin 使用标准的 Java 集合类
- 这对 Java 开发人员来说是个好消息: Kotlin 不会重新实现集合类
- 现有的所有 Java 集合知识 在这里依然适用
- 不过值得注意的是 ,与 Java 不同, Kotlin 的集合接口默认为只读
- 使用标准 Java 集合 可以更轻松地与 Java 代码交互
- 当从 Kotlin 调用 Java 函数 时,不需要转换集合,反之亦然
- 这对 Java 开发人员来说是个好消息: Kotlin 不会重新实现集合类
-
尽管 Kotlin 的基本集合与 Java 集合是完全相同的类
- 但在 Kotlin 中可以用它们做更多的事情
- 从列表中获取最后一个元素
- 获取列表的洗牌(shuffled)版本
- 对一个集合求和(假设它是一个数字集合)
- ...
- 但在 Kotlin 中可以用它们做更多的事情
kotlin
fun main() {
val strings = listOf("first", "second", "fourteenth")
println(strings.last())
println(strings.shuffled())
val numbers = listOf(1,2,4,5)
println(numbers.sum())
}
1.2 自定义 joinToString 函数来实现字符串打印
- 既然知道如何创建元素集合,我们就来做一件简单的事: 打印其中的内容
- Java 集合有一个默认的 toString 实现
- 但输出的格式是固定 的,并不总是你所需要的
- <1> 调用默认的 toString() 方法
- Java 集合有一个默认的 toString 实现
kotlin
fun main() {
val list = listOf(1, 2, 3)
println(list) // <1>
// [1, 2, 3]
}
-
试想一下,需要用分号分隔元素并用圆括号包围元素: (1; 2; 3)
- 为了解决这个问题
- Java 项目会使用 Guava 和 Apache Commons 等第三方库
- 或者在项目内部重新实现逻辑
- 在 Kotlin 中,标准库中有一个函数 可以处理这个问题
- 在本节中,你将亲自实现这个函数
- 为了解决这个问题
-
如下所示, joinToString 函数将集合中的元素追加到一个 StringBuilder 中
- 元素之间有分隔符 ,开头有前缀,结尾有后缀
- <1> 该函数是泛型函数 ,适用于包含任何类型元素的集合
- Kotlin中的泛型设计也很有意思,后面细讲
- <2> 不要在第一个元素前添加分隔符
- 正常来说, 除了泛型是新的知识点, 其他逻辑都应该看得懂才对
kotlin
fun <T> joinToString( // <1>
collection: Collection<T>,
separator: String,
prefix: String,
postfix: String
) : String {
val result = StringBuilder(prefix)
for ((index, elem) in collection.withIndex()){
if (index > 0) result.append(separator) // <2>
result.append(elem)
}
result.append(postfix)
return result.toString()
}
- 让我们来验证一下该功能是否能正常工作
- <1> 这个函数的实现符合预期, 大部分情况下可以保持原样
kotlin
fun main() {
val list = listOf(1, 2, 3)
println(joinToString(list, "; ", "(", ")"))
}
====================================== <1>
(1; 2; 3)
-
针对 joinToString 函数,思考以下几个问题?
- 如何修改声明才能使函数的调用不那么冗长?
- 每次调用调用该函数时都需要依次传递参数嘛?
- 可以打乱顺序进行参数传递嘛?
- 可以避免总是传递四个参数嘛?
-
下一节将彻底还原Kotlin标准库中 joinToString 扩展函数的实现细节