Kotlin Primer·第六章·集合泛型与操作符
2017-06-07 10:29
232 查看
本文开源实验室原创,转载请以链接形式注明地址:https://kymjs.com/code/2017/06/06/01
题外话:全书的目录以及主要内容已经公开,可在我公众号【技术实验室】的历史推送文章查看
第一部分——快速上手
第一章·启程
第二章·基本语法
第三章·Kotlin 与 Java 混编
第二部分——开始学习 Kotlin
第四章·Kotlin 的类特性(上)
第四章·Kotlin 的类特性(下)
第五章·函数与闭包
第六章·集合泛型与操作符
所谓泛型:就是允许在定义类、接口、方法时指定类型形参,这个类型形参将在声明变量、创建对象、调用方法时动态地指定(即传入实际的类型参数,也可称为类型实参)。
Kotlin 泛型定义与 Java 类似,但有着更多特性支持。首先,我们来看看集合类中的泛型声明。
以上是 Kotlin 的集合接口关系,从上到下,依次下面继承(或实现)上面的接口。
所有类声明的泛型尖括号里面如果加入了
相反的,如果没有加
泛型的
在看下面这个 demo 之前,你需要知道一点:Kotlin 的泛型是支持协变的。例如下面这段代码:
在 Kotlin 中,可以直接把
知道了上面这一点,我们接下来看
泛型声明中,用
类似的初始化集合对象的方法还有
还有很多,可以在
有一点需要知道的是,这些方法的返回值实际上返回的是 Java 的集合对象,目前只支持返回这些对象:
其他的对象,目前还不支持,比如
如果你使用过 RxJava 等一系列库,你一定会对操作符非常了解也对操作符的强大深有感触。
Kotlin 原生支持大量操作符,文尾将会列出常用操作符及含义。
这两幅图是我上周在《从 Java 到 Kotlin,当机器人不再喝咖啡》 技术分享时 PPT 中的两页,代码运行后是当时会场的 WiFi 密码,大家可以感受一下用 Kotlin 和 Java 实现的对比。
<img src="https://cdn.kymjs.com/kotlin/6-1-2.jpeg" alt="kotlin 集合类" style="width:80%"/>
<img src="https://cdn.kymjs.com/kotlin/6-1-3.jpeg" alt="kotlin 集合类" style="width:80%"/>
在 Kotlin 中,操作符本质上是方法调用。例如 List 的
而内部,实际上就是 for 循环对每一个对象调用传入的参数方法。
所以,我们也可以很轻松的通过这样的特性实现自己的自定义操作符。例如下面的代码为一个 List 添加一个转换操作符,可以将
这样子就可以直接调用 list 的 convert 方法,只需要实现转换逻辑,就可以了。
下标操作类
contains —— 判断是否有指定元素
elementAt —— 返回对应的元素,越界会抛IndexOutOfBoundsException
firstOrNull —— 返回符合条件的第一个元素,没有 返回null
lastOrNull —— 返回符合条件的最后一个元素,没有 返回null
indexOf —— 返回指定下标的元素,没有 返回-1
singleOrNull —— 返回符合条件的单个元素,如有没有符合或超过一个,返回null
判断类
any —— 判断集合中 是否有满足条件 的元素
all —— 判断集合中的元素 是否都满足条件
none —— 判断集合中是否 都不满足条件,是则返回true
count —— 查询集合中 满足条件 的 元素个数
reduce —— 从 第一项到最后一项进行累计
过滤类
filter —— 过滤 掉所有 满足条件 的元素
filterNot —— 过滤所有不满足条件的元素
filterNotNull —— 过滤NULL
take —— 返回前 n 个元素
转换类
map —— 转换成另一个集合(与上面我们实现的 convert 方法作用一样);
mapIndexed —— 除了转换成另一个集合,还可以拿到Index(下标);
mapNotNull —— 执行转换前过滤掉 为 NULL 的元素
flatMap —— 自定义逻辑合并两个集合;
groupBy —— 按照某个条件分组,返回Map;
排序类
reversed —— 反序
sorted —— 升序
sortedBy —— 自定义排序
sortedDescending —— 降序
题外话:全书的目录以及主要内容已经公开,可在我公众号【技术实验室】的历史推送文章查看
第一部分——快速上手
第一章·启程
第二章·基本语法
第三章·Kotlin 与 Java 混编
第二部分——开始学习 Kotlin
第四章·Kotlin 的类特性(上)
第四章·Kotlin 的类特性(下)
第五章·函数与闭包
第六章·集合泛型与操作符
所谓泛型:就是允许在定义类、接口、方法时指定类型形参,这个类型形参将在声明变量、创建对象、调用方法时动态地指定(即传入实际的类型参数,也可称为类型实参)。
Kotlin 泛型定义与 Java 类似,但有着更多特性支持。首先,我们来看看集合类中的泛型声明。
6.1 Kotlin 中的集合接口
<img src="https://cdn.kymjs.com/kotlin/6-1-1.png" alt="kotlin 集合类" style="width:80%"/>以上是 Kotlin 的集合接口关系,从上到下,依次下面继承(或实现)上面的接口。
所有类声明的泛型尖括号里面如果加入了
out关键字,则说明这个类的对象是只读的,例如他只有:get()、size()等方法,而没有 set()、remove()等方法。
相反的,如果没有加
out关键字,或者换一种记法:如果开头是
MutableXXX那就是一个跟 Java 中用法一致的集合类。
6.2 in 与 out
至此,你应该已经知道out关键字的含义了,与
out对应的,还有一个
in。表示泛型参数是只写的。
泛型的
in关键字一般用在我们定义的代码中。
在看下面这个 demo 之前,你需要知道一点:Kotlin 的泛型是支持协变的。例如下面这段代码:
open class A open class B : A() open class C : B() val mutableList: MutableList<B> = mutableListOf(B(), B(), C()) val list: List<A> = mutableList;
在 Kotlin 中,可以直接把
List<C>的对象赋值给
List<A>
知道了上面这一点,我们接下来看
in的用法。
泛型声明中,用
in声明泛型参数,表示这个参数只能是入参,不能对外返回这个参数。
open class A open class B : A() open class C : B() class TypeArray<in A> { //in 修饰了 A,表示 A 是可以作为参数的。 fun getValue(a: A): Int? { return a?.hashCode() } //这段代码是非法的,因为A 不能被返回 fun getA(a: A): A? { return a } }
6.3 集合的初始化
在 Kotlin 中,集合类一般不使用构造方法去初始化,而是使用同一的入口方法,例如初始化一个MutableList,我们使用的是如下代码:
val mutableList = mutableListOf(0, 1, 2, 3)
类似的初始化集合对象的方法还有
//创建一个 List<> 对象 var list = listOf(0, 1, 2) //创建一个 Set<> 对象 val ss = setOf(1, 2, 4)
还有很多,可以在
kotlin.collections.Collections.kt文件中查看。
有一点需要知道的是,这些方法的返回值实际上返回的是 Java 的集合对象,目前只支持返回这些对象:
java.util.ArrayList java.util.LinkedHashMap java.util.HashMap java.util.LinkedHashSet java.util.HashSet java.util.SortedSet java.util.TreeSet
其他的对象,目前还不支持,比如
LinkedList,个人觉得这个对象还是很常用的,不知道为什么没有方法提供,所以目前这类对象还是只能用构造方法去创建。
6.4 操作符
Kotlin 中,操作符是用来对数据做操作的工具方法。如果你使用过 RxJava 等一系列库,你一定会对操作符非常了解也对操作符的强大深有感触。
Kotlin 原生支持大量操作符,文尾将会列出常用操作符及含义。
这两幅图是我上周在《从 Java 到 Kotlin,当机器人不再喝咖啡》 技术分享时 PPT 中的两页,代码运行后是当时会场的 WiFi 密码,大家可以感受一下用 Kotlin 和 Java 实现的对比。
<img src="https://cdn.kymjs.com/kotlin/6-1-2.jpeg" alt="kotlin 集合类" style="width:80%"/>
<img src="https://cdn.kymjs.com/kotlin/6-1-3.jpeg" alt="kotlin 集合类" style="width:80%"/>
6.5 操作符实现原理
以最简单也是最常用的一个操作符forEach举例。
list.forEach { }
在 Kotlin 中,操作符本质上是方法调用。例如 List 的
forEach的实现原理实际上是定义了一个这样的方法。为 Iterable 增加了一个扩展方法,叫
forEach,它接收一个 T 作为参数,并返回 Unit 的闭包作为参数。
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit { for (element in this) action(element) }
而内部,实际上就是 for 循环对每一个对象调用传入的参数方法。
所以,我们也可以很轻松的通过这样的特性实现自己的自定义操作符。例如下面的代码为一个 List 添加一个转换操作符,可以将
List<A>转换成
List<B>,其中 A 和 B 可以为任何类型。
inline fun <T, E> Iterable<T>.convert(action: (T) -> E): MutableList<E> { val list: MutableList<E> = mutableListOf() for (element in this) list.add(action(element)) return list } { val list: List<String> = listOf("hello","world") list.convert { it.hashCode() }.forEach { print("$it") } }()
这样子就可以直接调用 list 的 convert 方法,只需要实现转换逻辑,就可以了。
6.6 常用操作符
Kotlin 的操作符跟 RxJava 基本一致,不需要额外记忆。下标操作类
contains —— 判断是否有指定元素
elementAt —— 返回对应的元素,越界会抛IndexOutOfBoundsException
firstOrNull —— 返回符合条件的第一个元素,没有 返回null
lastOrNull —— 返回符合条件的最后一个元素,没有 返回null
indexOf —— 返回指定下标的元素,没有 返回-1
singleOrNull —— 返回符合条件的单个元素,如有没有符合或超过一个,返回null
判断类
any —— 判断集合中 是否有满足条件 的元素
all —— 判断集合中的元素 是否都满足条件
none —— 判断集合中是否 都不满足条件,是则返回true
count —— 查询集合中 满足条件 的 元素个数
reduce —— 从 第一项到最后一项进行累计
过滤类
filter —— 过滤 掉所有 满足条件 的元素
filterNot —— 过滤所有不满足条件的元素
filterNotNull —— 过滤NULL
take —— 返回前 n 个元素
转换类
map —— 转换成另一个集合(与上面我们实现的 convert 方法作用一样);
mapIndexed —— 除了转换成另一个集合,还可以拿到Index(下标);
mapNotNull —— 执行转换前过滤掉 为 NULL 的元素
flatMap —— 自定义逻辑合并两个集合;
groupBy —— 按照某个条件分组,返回Map;
排序类
reversed —— 反序
sorted —— 升序
sortedBy —— 自定义排序
sortedDescending —— 降序
相关文章推荐
- Kotlin Primer·第六章·集合泛型与操作符
- Kotlin Primer · 集合泛型与操作符
- 泛型集合的序列化和反序列化
- 黑马程序员----集合框架、泛型
- 集合框架-泛型方法的概述和使用
- C#泛型-泛型集合Dictionary<K,V>
- 异常、集合与泛型
- c#泛型集合
- 集合类及泛型
- JAVA-10-算法、集合、Collection、List等、泛型入门
- Java的集合与泛型
- 集合框架(静态方法泛型)
- 泛型集合代替DataTable
- 集合和泛型8-----装箱、拆箱与类型安全
- 泛型集合
- 黑马程序员_集合2(HashSet,TreeSet,JDK1.5新特性泛型)
- 集合与泛型
- 8.Java中的集合、枚举、泛型【上】
- java中利用泛型构建的collection集合
- [javaEE] 反射-通过反射了解集合泛型本质