Kotlin并没有实现集合类,它仅仅是对Java集合类的重用, 另外扩展了一些函数。 我们下面要讲的就是那些扩展的函数。
这里声明一下,笔记在文中,"函数"和"方法"都是混着写的,没有去区分。如果非要分的很清楚,那么在类里面的叫方法,而函数是类外面的。
kotlin和Java不同的地方是可以在类外面写方法,这个和C++一样,所以C++中也是叫函数,而不是方法,Java不能在类外面写,只能在类里面写,所以叫方法。
接下来要讲的扩展函数,都是在类外面写的,所以叫函数。
-
创建不可变List
所谓的不可变List就是:list中没有添加删除性质的api。
创建不可变List有三个函数:
- listOf(),创建没有元素的空list。返回的是Kotlin的EmptyList类对象。和Java中的EmptyList差不多,只不过泛型是Nothing。另外创建list的变量不能匿名,因为要指定泛型。
- listOf(element:T), 用于创建只有一个元素的List。代码跟下去,会发现调用了java的SingletonList。
- listOf(vararg element:T), 用于创建拥有多个元素的List。它调用的是java的,java.util.Arrays$ArrayList, 这是一个ArrayList是对一个固定大小数组的封装。注意和java.util.ArrayList是不一样的。
- listOfNotNull(vararg element:T),去除null元素。
-
创建可变List,也就是MutableList
和不可变List相反,不仅有不可变List的读取api, 还有添加/删除性质的api。另外,这种命名方式让笔者想起了LiveData/MutableLiveData, 也是这种命名方式,MutableLiveData可以setValue(), 而LiveData只能读取。这种方式是借鉴与另外一种JVM语言叫Scala。
创建可变List的函数:
- mutableListOf(),实际背后调用的就是java.util.ArrayList。
- arrayListOf和mutableListOf一样的结果,也是java.util.ArrayList。
-
不可变List和可变MutableList的转换
- 不可变List到可变List, 调用List的toMutableList()就好了。
- 可变List到不可变List, 调用List的toList()就好了。或者把不可变List对象赋值给一个List变量就好了。
-
遍历List
- 用Iterator/MutableIterator遍历。MutableIterator有remove函数。
- 用ListIterator/MutableListIterator遍历链表。可前可后,MutableListIterator可删除可添加。
- for循环/elementAt()/get(index)。以及[下标]。 elementAt其实还是调用了get(index)
- foreach, 这是一个语法糖,实际使用的还是Iterator。当参数只有一个函数时,括号()可以不写。 下面三种写法是等价的。::是函数引用符。
list.foreach{
print(it)
}
list.foreach({
print(it)
})
list.foreach(::println)
-
List元素操作函数
基本和java8里面差不多,这儿只讲一些稍微特别一点的函数。总的来说,能满足sql对数据库的查询一样。以后想到查询过滤的时候,想起这句话就够了
- elementAt(index), 里面还是调用了get(index)。
- 相对于elementAt。 elementAtOrElse()在越界时,可以返回指定的值。而elementAtOrNull(index), 当越界时返回null。
- retainAll, 就是获取两个list的交集。
- 一些查询的函数,都有一Predicate函数用于筛查元素。
- single()/single(Predicate)函数, 如果只有一个元素就返回元素,不然抛异常。如果不想抛异常,就用singleOrNull()
- any/all/none, 这三个函数, 有满足一个条件/满足所有条件/一个也没有。 这三个都有Predicate函数引用。
- count, 统计满足条件的个数。
- 过滤操作函数。
- 查找操作函数。
10. 映射操作符函数。把list里的元素,做一个转换后,再生成一个新的List。很类似RxJava里的map/flatmap。
11. 生成操作函数。合并,拆开,就做这两件事。
12. 排序操作函数
- 倒序:reserved/reserve, 都一样,其中reserved调用了reserve。
- sorted(升序), sortedDescending(降序)。
- 指定方式的排序, sortby(), sortbyDescending()
13.分组操作函数 (暂时理解有困难,等学习了函数编程再来填这个坑)
- groupBy(key:(T) ->K):Map<K, List<T>>,我们把key叫输入, K叫输出,List<T>叫分组结果。从函数签名可以看出返回结果的Map中, 输出是Key, 分组结果
-
Set集合
Kotlin中的Set也分为可变MutableSet和不可变Set。
- 创建Set, setOf()/mutableSetOf(), 默认创建的是Java的LinkedHashSet。插入删除效率高,查询速度和HashSet一样。就是多占了一个链表的内存
- Aarry/List含有toSet()函数, 可以去重。
- Set区分不同对象是靠hashcode/equal。所以有时需要根据需求重写这两个函数。
- MutableSet和Set, 也可以相互转变。
- Kotlin和Java一一对应的函数是这样的: hashSetof():HashSet, linkedSetOf:LinkedHashSet, sortedSet():TreeSet
- 加减操作plus和minus, Kotlin对Set增加了加减运算的扩展函数。
val ms = mutableSetOf(1,3,2,7)
ms+10 //这时ms,添加元素“10”, 变成了(1,3,2,7,10)
ms - 2 //这时ms,删除了元素“2”, 变成了(1,3,7,10)
ms - listOf(1,3,7) //这时ms,删除了元素“1”,“3”,“7”, 变成了(2)
-
Map
同样,Map也分为可变MutableMap和不可变Map。
- 创建方式如下表:需注意的是mapOf/mutableMap创建的都是Java的LinkedHashMap。
2. to操作, 这是一个扩展的二元操作符,用来快速生成Pair<K,V>。以前讲过的。创建Map时是接受Pair方式的。
var map1 = mapOf(20 to "alan", 30 to "gong")
var map2 = mapOf(Pair(20,"alan"), Pair(30, "gong")) // map1和map2是等价的,两者都可以。
3. map.keys和map.values都返回相对于的Set集合。
4. 查询方式, map[key],不存在返回null, 或者map.get(key)。
5. map.get(key)不想返回null, 就用getOrDefualt(),没有时返回你设定的默认值。但是默认值的类型必须和Value的类型一样。
6. 更多的操作符函数看下图:
再提getOrElse, getOrPut看起来很有用的样子。还有一些filter, mapKeys, mapValues等。
7. 支持解构。看上图的component1和component2。非常适合在遍历map的时候直接使用key或value,你可以这样使用:
for ((k,v) in map){
println("$k------$v")//输出key和value
}
for ((k) in map){
println("$k") //输出key
}
8. toPair函数, 可以把Map的Entry转换成Pair<K,V>