多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 集合 在程序中,可以通过数组来保存多个对象,但是当无法确定到底需要保存多少个对象时,此时数组将不再适用,因为**数组的长度不可变**。例如,要保存一个学校的学生信息,由于不停地有新生来报道,同时也有学员毕业离开学校,这时学生的数目很难确定。为了保存这些数目不确定的对象,Kotlin提供了一系列特殊的类,这些类可以存储任意类型的对象,并且长度可变,统称为集合。下图是Kotlin 集合接口的图表 ![](http://www.kotlincn.net/assets/images/reference/collections-overview/collections-diagram.png) ### [集合概述](https://www.kancloud.cn/alex_wsc/android_kotlin/1318319) Kotlin中的集合就类似一个容器,用于存储一系列对象,这些对象**可以是任意的数据类型,并且长度可变**。这些类都存放在`kotlin.collections`包,在使用时一定要注意导包的问题,否则会出现异常。 集合按照其存储结构可以分为两大类,即单列集合Collection和双列集合Map,这两种集合的特点具体如下。 #### Collection Iterable是单列集合类的根接口,而通常在使用时是从Collection接口开始,Collection用于存储一系列符合规则的元素,它有**3个重要的子接口**,分别是**List、Set和MutableCollection**。其中,**List的特点是元素有序、元素可重复。Set的特点是元素无序并且不可重复(`Set`的默认实现 -[`LinkedHashSet`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-linked-hash-set/index.html)– 保留元素插入的顺序)。Mutable Collection的特点是元素可变**。下面的图例展示了一个Collection中的继承关系,如图所示。 ![](https://img.kancloud.cn/29/01/29014e181b9715dcb46c4216486fb09c_1332x617.png) 从图可以看出,**Collection继承自Iterable接口,Collection有3个子接口,分别为List、Set、MutableCollection,而且MutableCollection接口不仅继承Collection接口还继承MutableIterable接口**。 >[info]需要注意的是,图中**虚线框标识的都是Java中的集合类,但是这些类可以在Kotlin中使用**。**List接口在Kotlin中有两个实现类,分别为ArrayList、MutableList**,而LinkedList是Java中的实现类。**Set接口在Kotlin中同样也只有两个实现类,分别为HashSet和MutableSet**,而TreeSet也是Java中的实现类。 **Collection是所有单列集合的父接口**,因此在Collection中定义了单列集合(List、Set、MutableCollection)通用的一些方法,这些方法可用于操作所有的单列集合,如表所示。 ![](https://img.kancloud.cn/41/21/4121804738e5035abfd50ecb94ecfab3_1361x637.png) #### Map **Map是双列集合类的根接口,用于存储具有键(Key)、值(Value)映射关系的元素**,每个元素都包含一对键值,在使用Map集合时可以通过指定的Key找到对应的Value。例如根据每个人的身份证号就可以找到对应的人。接下来通过一个图例来展示一下Map中的继承关系,如图所示。 ![](https://img.kancloud.cn/60/5c/605c3705da5391dd860eeeb5d250b5aa_1255x595.png) Map接口有3个子接口,分别为HashMap、TreeMap、MutableMap,HashMap有一个实现类LinkedHashMap。 需要注意的是,TreeMap是Java中的集合接口。 ### 集合定义 从这节开始,我们将学习Kotlin中的集合。如果将区间比喻为MP3,那么集合就是现在的智能手机,MP3只能播放音乐,而手机不仅可以播放音乐还可以播放视频。 简而言之,就是区间只能存储简单数据类型,但是集合除了可以存储基本数据类型,还可以存储自定义的数据类型,功能更强大。集合是Kotlin中非常重要的知识点,开发中经常使用集合缓存数据,比如商品信息等。 ### 集合分类 同Java,集合分为三种类型,分别是List、Set和Map集合。分别对应了List、Set和Map三个接口。其中**List、Set接口默认实现了Collection接口**,参考类继承截图: ![](http://upload-images.jianshu.io/upload_images/7368752-25f4861cebb17bb8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **Map接口没有实现任何其他接口**。 List、Set和Map集合各自特点和区别是什么呢?我们通过一个表列举下: | **集合** | **特点** | | ---------- | ---------------------------------------- | | | (1)实现Collection接口 | | **List** | (2)存储的**元素有序**、**可重复** | | | (3)常用子类MutableList、ArrayList、LinkedList(Java独有)等 | | | (1)实现Collection接口 | | **Set** | (2)存储的**元素无顺序**、**不重复** | | | (3)常用子类MutableSet、HashSet、TreeSet(Java独有)等 | | **Map** | (1)**不实现Collection接口** | | | (2)存储的是键值对key-value | | | (3)存储的元素无序,键唯一,值value允许重复 | | **Map** | (4)常用子类HashMap、LinkedHashMap | ### 集合可写&(不可写) Java中集合和Kotlin中的集合大同小异。两者有一个非常大的区别就是,Java中的List、Set、Map集合都是可读可写的。**Kotlin中List、Set、Map的集合在读方面都是可读的,在写方面则分为可写和不可写集合**。 Java中List、Set集合都实现了Collection接口,Java中的Collection接口就已经包含了add方法,所以Java中所有List、Map集合都是可写的,参考Java中Collection接口的Structure截图: ![](https://img.kancloud.cn/51/da/51dab09283997747732e67184d3668a6_572x588.png) Kotlin中的List、Set集合都实现了Collection接口,但Kotlin中的Collection接口并没有包含add方法,参考Kotlin中Collection的Structure截图: ![](http://upload-images.jianshu.io/upload_images/7368752-ada6caef09b52fc4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 那add方法定义到哪里去了呢?**Kotlin为Collection新增一个子接口MutableCollection,add方法定义到了MutableCollection中**,参考Kotlin中MutableCollection结构图: ![](https://img.kancloud.cn/f1/84/f184beada86c810b8661bbcc298d7f5d_469x571.png) 所以,只要实现了MutableCollection的List、Set集合都是可写的。MutableList、MutableSet都是实现了MutableCollection接口的集合。 Java中Map集合都实现了Map接口,Java中的Map接口就已经包含了put方法,所以Java中所有Map集合都是可写的,参考Java中Map接口的Structure截图: ![](http://upload-images.jianshu.io/upload_images/7368752-50e4f836ada185e6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) Kotlin中的Map集合都实现了Map接口,但Kotlin中的Map接口并没有包含put方法,参考Kotlin中Map接口的Structure截图: ![](http://upload-images.jianshu.io/upload_images/7368752-fe9339d48a74572a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 那put方法定义到哪里去了呢?Kotlin为Map接口新增一个子接口MutableMap,put方法定义到了MutableMap接口中,参考Kotlin中MutableMap接口的Structure截图: ![](http://upload-images.jianshu.io/upload_images/7368752-b4058ea0099f0c99.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 所以,只要实现了MutableMap的Map集合都是可写的。MultiHashtable都是实现了MutableCollection接口的集合,使用MutableCollection创建的map集合都是可写的。 总结起来就是,**使用MutableList、MutableSet、MutableMap创建的集合都是可写的**, Mutable的意思本来也是“易变的,性情不定的”。 ### 类型别名TypeAliases 类型别名为现有类型提供替代名称。 如果类型名称太长,你可以另外引入较短的名称,并使用新的名称替代原类型名。它有助于缩短较长的泛型类型。你可以为函数类型提供另外的别名,你可以为内部类和嵌套类创建新名称,类型别名不会引入新类型。 它们等效于相应的底层类型。 **TypeAliases.kt源码**如下   ~~~ @file:Suppress("ACTUAL_WITHOUT_EXPECT") // for building kotlin-stdlib-minimal-for-test package kotlin.collections @SinceKotlin("1.1") public actual typealias RandomAccess = java.util.RandomAccess @SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E> @SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V> @SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V> @SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E> @SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E> ~~~ 参考官方文档——[类型别名](http://www.kotlincn.net/docs/reference/type-aliases.html)