爱站网挖掘关键词,产品设计方案怎么写,wordpress显示分类,wordpress/原文链接 Kotlin Collections
现代的软件一般比较复杂#xff0c;程序语言中的基本数据类型往往不能满足需要#xff0c;除了基本的数据类型以外#xff0c;还有对象的容器也非常的重要#xff0c;比如线性容器#xff08;数组#xff0c;列表和Set#xff09;和二维容…原文链接 Kotlin Collections
现代的软件一般比较复杂程序语言中的基本数据类型往往不能满足需要除了基本的数据类型以外还有对象的容器也非常的重要比如线性容器数组列表和Set和二维容器哈希表等。今天就来学习一下Kotlin中的容器。 Kotlin Collections
集合就是用于处理一组对象的容器因为用的人较多所以就成了标准库。常见的集合有三种主要类型列表类Set类和Map类。
线性容器
这里并不单纯指类List主要的意思是线性的容器它的特点是以相对顺序存储同一类型的对象有一个整数索引(index)来表示其相对的位置查找性能差其他还好。代表为数组。
数组
最简单也是使用最为广泛的线性容器不用过多的介绍了可以参考之前的文章。
最大的弊端就是长度是固定的长度在创建数组时就确定了后面就改不了了。所以必须在事先要能够确定数组的长度。
创建复杂数组
比如数组的元素是一个Collection而非常见的基本数据类型这时要如何写 val carray arrayOfMutableListInt(mutableListOf(),mutableListOf())val narray ArrayMutableListInt(10) { mutableListOf() }关键就在于要声明元素的类型其他的与基本数据类型的数组是一样的。另外如果数组数量比较少方便直接写那就用字面构造函数其实很方便。或者用数组元素的构造方法也可以。
多维数组
以最为常见的二维数组来说要如何创建? val smatrix arrayOf(arrayOf(1, 2, 3),arrayOf(4, 5, 6),arrayOf(7, 8, 9))val matrix Array(5) { IntArray(6) }Ranges
用于表示区间的表达式最为直观理解就是数组的索引用操作符…来表示区间比如0~9就是0…9通常用于for-loop中
if (i in 1..4) { // equivalent of i 1 i 4print(i)
}for (i in 1..4) print(i) // for (int i 1; i 4; i) print(i)还可以指定步长和边界以及方向
for (i in 0 until 10) { // for (int i 0; i 10; i)print(ln)
}for (i in 0 until 10 step 2) { // for (int i 0; i 10; i 2)print(ln)
}for (i in 9 downTo 0) { // for (int i 9; i 0; i--)print(i)
}还可以用于字符比如
for (c in a..z) { // for (char c a; c z; c)print(c)
}Range是一个表达式所以在其之上做其他操作但需要注意这时需要加上括号比如 for (i in (0..9).filter {it % 2 0 }) {println(i) // only evens}for (c in (a..z).map { it.toUpperCase() }) {println(c) // upper case}需要注意虽然Ranges方便操作数组的索引但如果想要带着索引遍历数组的话还是要用专用的遍历方式而不是用Range比如
for ((index, value) in array.withIndex()) {println(the element: [$index] $value)
}注意与repeat的区别
Ranges是一个数据结构代表着一个区间这个区间可能是一个整数范围也可能是一个字符范围其实也可以是其他自定义数据类型只要能表达 出区间的概念。只不过整数区间是为常用的一种方式以及整数区间可以方便当作数组和列表的索引。
但有时如果仅仅想重复一件事情n次那就没有必要用Ranges虽然它也可以这时最为方便的是函数repeat它与区间的唯一区别是repeat是没有返回值的它仅是把一件事情重复n次但没有返回值也就是说没有办法再转化为其他数组或者列表。
repeat(10) { println(repeat # $it) }
//repeat # 0
//repeat # 1
//repeat # 2
//repeat # 3
//repeat # 4
//repeat # 5
//repeat # 6
//repeat # 7
//repeat # 8
//repeat # 9而比如Ranges是可以转化为其他数组和列表的
(0 until 5).map { it * it }.toIntArray()
// [0, 1, 4, 9, 16]列表List
列表可以简单理解为无限长的数组它最大的特点是长度不固定不必事先定好长度它会随着添加元素而自动增长。所以当你事先不知道容器的长度时就需要用List。它是一个泛型其余操作与数组一样。
val names listOf(James, Donald, Kevin, George)
names.map { it.toUpper() }.forEach { println(it) }序列Sequence
序列与列表比较难区分直观上它们是一样的。简单来说它并不是容器它并不持有对象它生产对象类似于物理上的信号发射器和RxJava中的Observable是有时序上的概念的当你需要时它就生产出来一个元素。
队列queue
队列可以用双端队列deque读作dek具体实现对象是ArrayDequeT。
双端队列是强大的数据结构即可以用作队列也可以用作栈。
Set容器
Set是一个不含有重复元素的容器特点是不会保存相对顺序可以快速实现检索。 val names setOf(James, Harden, Donald, Joe)for (nm in names) {println(nm)}names.filter { it.length 4 }.forEach { println(it) }Map容器
由映射键-值对组成的二维容器键不可重复值可以重复不会保存相对顺序也可以用于快速检索。 val nameMap mapOf(James to 15, Harden to 30, Donald to 80, Joe to 86)for (nm in nameMap.keys) {println(nm)}for (age in nameMap.values) {println(age)}for (e in nameMap.entries) {println(${e.key} is ${e.value})}nameMap.filter { it.key.length 5 }.forEach { println(${it.key} ${it.value}) }注意Immutability
有一个地方需要特别注意那就是容器的不可变性Immutability用常规的方法创建的集合对象是不可变的Immutable就是无法向其中添加元素也无法删除元素。对象的不可变Immutable在函数式编程中是很重要的特性可以有效的减少异步和并发带来的状态一致性问题。
val names listOf(James, Donald, Kevin, George)
names.add(Paul) // compile error, names is immutable
names.map { it.toUpper() }.forEach { println(it) }这样写会有编译错误因为用listOf创建的列表对象是不可变的Immutable。如果想要改变就必须用支持更改的对象如MutableList, MutableSet和MutableMap如
val names mutableListOf(James, Donald, Kevin, George)
names.add(Paul) // okay
names.map { it.toUpper() }.forEach { println(it) }如果有可能还是要尽可能的用不可变对象(Immutable objects)。
集合的操作
集合的操作就是函数式的三板斧过滤filter转化map和折叠化约fold/reduce前面讲的所有的容器都是支持的结合lambdas可以写出非常规范的函数式代码。
参考资料
Kotlin CollectionsKotlin常用Collection集合操作整理Kotlin Collections GuideKotlin Ranges
原创不易打赏点赞在看收藏分享 总要有一个吧