Kotlin入门第二课:集合操作
测试项目Github地址:
前文传送:
1. 介绍
作为Kotlin入门的第二课,不打算按照教程从基础数据类型开始,而是直接学习至关重要的集合部分。因为一般的应用开发都离不开数据,数据处理就要用到集合,而只有深入了解集合,包括概念及不同类型的集合分别实现了哪些方法,才能在需要的时候快速选出最合适的集合与对应的操作。因此,迫不及待地想给大家展示Kotlin集合的魅力,基础数据类型的用法会放到后续的文章进行整理。
Kotlin中的集合主要有以下几种:
Iterable--An iterator over a collection or another entity that can be represented as a sequence of elements;
MutableIterable--An iterator over a mutable collection. Provides the ability to remove elements while iterating;
Collection--A generic collection of elements. Methods in this interface support only read-only access to the collection;
MutableCollection--A generic collection of elements that supports adding and removing elements;
List--A generic ordered collection of elements. Methods in this interface support only read-only access to the list;
MutableList--A generic ordered collection of elements that supports adding and removing elements;
Set--A generic unordered collection of elements that does not support duplicate elements;
MutableSet--A generic unordered collection of elements that does not support duplicate elements, and supports adding and removing elements;
Map--A collection that holds pairs of objects (keys and values) and supports efficiently retrieving the value corresponding to each key. Map keys are unique; the map holds only one value for each key;
MutableMap--A modifiable collection that holds pairs of objects (keys and values) and supports efficiently retrieving the value corresponding to each key. Map keys are unique; the map holds only one value for each key;
不专业的翻译会误导读者,所以这里就不献丑了,相信这段英文解释对程序员来说不成问题。
2. 操作方法
涉及到的代码在KotlinForJava的Kotlin1项目中,针对集合List和MutableList的操作进行测试,参考的是Kotlin中文学习资料,前面给出的文章中能找到相应的资源链接。
学习的同时通过编码练习是很有必要的,除了加深理解还可以发现资料中存在的问题,常见的如IDEA或API更新了而资料是旧的,花时间去学习已经废弃的方法就不值得了。所以,建议英文好的通过官网给出的资料来学习是最好的,上面的信息一般会及时更新。
先定义两个List对象,后面的操作会用到。
val list = listOf(, , , , , , , , , )
val mutableList = mutableListOf(, , , , , , , , , )
2.1 总数操作
测试代码:
println(list.any { it % == })
println(list.all { it % == })
println(list.count { it % == })
println(list.fold() { total, next -> total + next })
println(list.foldRight() { total, next -> total + next })
list.forEach { value -> if (value > ) println(value) }
list.forEachIndexed { index, value -> if (value > ) println("value of index $index is $value") }
println(list.max())
println(list.maxBy { -it })
println(list.min())
println(list.minBy { -it })
println(list.none { it % == })
println(list.reduce { total, next -> total + next })
println(list.reduceRight { total, next -> total + next })
println(list.sumBy { it % })
方法作用:
any--判断集合中是否有满足条件 的元素;
all--判断集合中的元素是否都满足条件;
count--查询集合中满足条件的元素个数;
fold--在给定初始值的基础上,从第一项到最后一项进行累加;
foldRight--在给定初始值的基础上,从最后一下到第一项进行累加,与fold只是的方向不同;
forEach--循环遍历元素,元素是it,可对每个元素进行相关操作;
forEachIndexed--循环遍历元素,同时得到元素index(下标);
max--查询最大的元素,如果没有则返回null;
maxBy--获取方法处理后返回结果最大值对应的那个元素的初始值,如果没有则返回null;
min--查询最小的元素,如果没有则返回null;
minBy--获取方法处理后返回结果最小值对应那个元素的初始值,如果没有则返回null;
none--判断集合中是否都不满足条件,是则返回true;
reduce--与fold区别在于没有初始值,或者说初始值为0,从第一项到最后一项进行累加;
reduceRight--从最后一项到第一项进行累加,与reduce只是方向的不同;
sumBy--获取方法处理后返回结果值的总和;
建议将文字解释和代码结合起来理解方法的作用,先对结果有一个预判,然后看下面的打印信息。
打印结果:
true
false value of index is true
2.2 过滤操作
测试代码:
println(list.drop())
println(list.dropWhile { it < })
println(list.dropLastWhile { it < }) println(list.filter { it % == })
println(list.filterNot { it % == })
println(list.filterNotNull()) println(list.slice(listOf(, , )))
//println(list.slice(listOf(0, 4, 80))) //java.lang.ArrayIndexOutOfBoundsException: 80 println(list.take())
println(list.takeLast())
println(list.takeWhile { it < })
方法作用:
drop--返回去掉前n个元素后的列表;
dropWhile--返回从第一项起,去掉满足条件的元素,直到不满足条件的一项为止;
dropLastWhile--返回从最后一项起,去掉满足条件的元素,直到不满足条件的一项为止;
filter--过滤掉所有不满足条件的元素;
filterNot--过滤掉所有满足条件的元素;
filterNotNull--过滤掉所有值为null的元素;
slice--过滤掉非指定下标的元素,即保留下标对应的元素过滤List中指定下标的元素(比如这里只保留下标为1,3,4的元素),当过滤list中有元素值大于目标List大小时会出现异常;
take--返回从第一个开始的n个元素;
takeLast--返回从最后一个开始的n个元素;
takeWhile--返回不满足条件的下标前面的所有元素的集合;
代码中有一行注释,关于slice操作,在实际使用时需要注意过滤List中的元素值,以免出现ArrayIndexOutOfBoundsException异常。
打印结果:
[, , , , , ]
[]
[, , , , , , , , , ]
[, , , , ]
[, , , , ]
[, , , , , , , , , ]
[, , ]
[, ]
[, ]
[, , ]
2.3 映射操作
测试代码:
println(list.flatMap { listOf(it, it + ) })
println(list.groupBy { if (it % == ) "even" else "odd" })
println(list.map { it * })
println(list.mapIndexed { index, it -> index * it })
println(list.mapNotNull { it * })
方法作用:
flatMap--合并两个集合,可以在合并的时候对迭代元素值it多想要的操作;
groupBy--将集合中的元素按照某个条件分组,返回Map;
map--将集合中的元素通过某个方法转换后的结果存到一个集合中;
mapIndexed--除了得到转换后的结果,还可以拿到index(下标);
mapNotNull--执行方法转换前过滤掉为null的元素;
打印结果:
[, , , , , , , , , , , , , , , , , , , ]
{even=[, , , , ], odd=[, , , , ]}
[, , , , , , , , , ]
[, , , , , , , , , ]
[, , , , , , , , , ]
2.4 元素操作
测试代码:
println(list.contains()) println(list.elementAt())
//println(list.elementAt(11)) //java.lang.ArrayIndexOutOfBoundsException: 11
println(list.elementAtOrElse(, { * it }))
println(list.elementAtOrNull()) println(list.first { it % == })
//println(list.first { it % 2 == 10 }) //java.util.NoSuchElementException: Collection contains no element matching the predicate
println(list.firstOrNull() { it % == }) println(list.indexOf())
println(list.indexOfFirst { it % == })
println(list.indexOfLast { it % == }) println(list.last { it % == })
//println(list.last { it % 2 == 10 }) //java.util.NoSuchElementException: List contains no element matching the predicate
println(list.lastIndexOf())
println(list.lastOrNull { it % == }) println(list.single { it % == })
//println(list.single { it % 2 == 0 }) //java.lang.IllegalArgumentException: Collection contains more than one matching element
println(list.singleOrNull() { it % == })
方法作用:
contains--判断集合中是否有指定元素,有则返回true;
elementAt--查找下标对应的元素,如果下标越界会抛IndexOutOfBoundsException异常;
elementAtOrElse--查找下标对应元素,如果越界会根据方法返回默认值(最大下标经方法后的值);
elementAtOrNull--查找下标对应元素,越界会返回Null;
first--返回符合条件的第一个元素,没有则会抛NoSuchElementException异常;
firstOrNull--返回符合条件的第一个元素,没有返回null;
indexOf--返回指定下标的元素,没有返回-1;
indexOfFirst--返回第一个符合条件的元素下标,没有返回-1;
indexOfLast--返回最后一个符合条件的元素下标,没有返回-1;
last--返回符合条件的最后一个元素,没有则会抛NoSuchElementException异常;
lastIndexOf--返回符合条件的最后一个元素,没有返回-1;
lastOrNull--返回符合条件的最后一个元素,没有返回null;
single--返回符合条件的单个元素,如有没有符合的或符合超过一个分别会抛NoSuchElementException或IllegalArgumentException异常;
singleOrNull--返回符合条件的单个元素,如有没有符合或超过一个,返回null;
可以看到,容易出现异常的操作Kotlin会给出另一个安全调用的替代,如first与firstOrNull。
打印结果:
true null null null null
2.5 生产操作
测试代码:
println(list.partition { it % == })
println(list + listOf(, ))
println(list.zip(listOf(, )))
println(listOf(Pair(, ), Pair(, )).unzip())
方法作用:
partition--根据判断条件是否成立,拆分成两个Pair;
plus--合并两个List,可以用"+"替代;
zip--两个集合按照下标组合成一个个的Pair塞到集合中返回;
unzip--将包含多个Pair的List转换成含List的Pair;
Pair对象的数据组成形式为(first, secord),即Pair(1, 2).first可以取出数据1。
注意:文档和网上一些老的资料还提到了merge操作,编码时提示找不到符号,查资料发现从Kotlin 1.0 Beta 2后的版本开始就弃用了。
打印结果:
([, , , , ], [, , , , ])
[, , , , , , , , , , , ]
[(, ), (, )]
([, ], [, ])
2.6 排序操作
测试代码:
println(list.reversed()) println(list.sorted())
println(list.sortedBy {it % }) println(list.sortedDescending())
println(list.sortedByDescending { it % })
方法作用:
reversed--相反顺序;
sorted--自然排序(升序);
sortedBy--根据方法处理结果进行自然(升序)排序;
sortedDescending--降序排序;
sortedByDescending--根据方法处理结果进行降序排序;
注意:新版kotlin需要调用sorted()这样带"ed"后缀的方法才能返回List,而sort()是返回Unit。那么这两种方法还有哪些区别,或者说分别在什么场景下使用?
还是以sort为例,sorted()处理过程中会新建临时的List来保存结果数据,对原来的调用者List不会做任何改变,所以需要将新建的对象返回;而sort()是在原来的List基础上进行元素顺序的调整,不会新建对象,所以不需要返回List。
打印结果:
[, , , , , , , , , ]
[, , , , , , , , , ]
[, , , , , , , , , ]
[, , , , , , , , , ]
[, , , , , , , , , ]
开头部分还定义了一个MutableList对象,下面就结合不带"ed"后缀的排序方法对其进行操作。
1 mutableList.reverse()
2 println(mutableList)
打印输出:
[, , , , , , , , , ]
如果用list对象调用reverse()会提示List没有该方法,算是各尽其职。而将list打印出来发现果然还是初始化时的顺序:
[, , , , , , , , , ]
3. 总结
本文对集合类型List(MutableList针对排序)的总数、过滤、映射、元素、生产及排序六种操作进行了测试,指出了可能出现异常的地方,通过比较加深了List和MutableList这种对应类型的联系与区别。有些操作在Kotlin中只需一句代码就可以得到结果,而在Java中需要手动通过普通的循环或迭代器来对集合中的元素逐一进行处理。
对于Set等其他集合类型,对象创建和操作与List类似,这里不一一举出了。
Kotlin入门第二课:集合操作的更多相关文章
- 数据结构入门第二课(浙大mooc)
数据结构入门第二课 目录 数据结构入门第二课 引子 多项式的表示 方法1 顺序结构表示多项式各项 方法2 顺序结构表示非零项 方法3 链表结构存储非零项 多项式问题的启示 线性表 线性表的抽象数据类型 ...
- Hibernate入门第二课 Hibernate Tools for Eclipse Plugins安装
Hibernate入门第二课 Hibernate Tools for Eclipse Plugins安装 你们可以直接去,http://blog.csdn.net/wei_chong_chong/ar ...
- Kotlin入门第一课:从对比Java开始
1. 介绍 今年初,甲骨文再次对谷歌所谓的安卓侵权使用Java提起诉讼,要求后者赔偿高达90亿美元.随后便传出谷歌因此计划将主力语言切换到苹果主导的Swift,不过这事后来没了跟进. 但谷歌在这两天的 ...
- Kotlin入门(27)文件读写操作
Java的文件处理用到了io库java.io,该库虽然功能强大,但是与文件内容的交互还得通过输入输出流中转,致使文件读写操作颇为繁琐.因此,开发者通常得自己重新封装一个文件存取的工具类,以便在日常开发 ...
- Kotlin入门(4)声明与操作数组
上一篇文章介绍了基本变量类型在Kotlin中的用法,不过这只针对单个变量,如果要求把一组相同类型的变量排列起来,形成一个变量数组,那又该如何声明和操作呢? 在Java中声明数组,跟在C语言中声明是一样 ...
- Spring入门第二课:Spring配置Bean的细节
1.配置bean的作用域: 通过配置scope属性可以bean的作用域,参数有 prototype.request.session.singleton. 1)singleton为单例,IoC容器只会创 ...
- MySQL入门第二天——记录操作与连接查询
常见SQL语法,请参见w3school:http://www.w3school.com.cn/sql/sql_distinct.asp 易百教程:http://www.yiibai.com/sql/f ...
- Spring入门第二课
看代码 package logan.spring.study; public class HelloWorld { private String name; public void setName2( ...
- mysql 第二课 DML操作
DML 数据操纵语句:INSERT UPDATE DELETE SELECT 主要用来对数据库的数据进行一些操作; DCL 数据定义语句:CREATE ALTER DROP 主要是用在定义或改变表的 ...
随机推荐
- git常见操作和常见错误
最近写了个博客demo,在上传至github时,居然报错了,刚开始学习代码上传,免不了遇到一些问题,报错信息如下: fatal: remote origin already exists. (致命错误 ...
- 高性能MySQL--索引学习笔记(原创)
看过一些人写的学习笔记,完全按书一字不漏照抄,内容很多,真不能叫笔记.遂自己整理了一份,取其精要. 更多笔记请访问@个人简书 [toc] 索引概述 索引即key 在存储引擎层实现,不同引擎工作方式不同 ...
- C++ fstream 详解
最近在写哈夫曼压缩,遇到了一个比较让人头疼的问题,那就是对文件的读写操作,尤其是以二进制的形式来读写,无奈C++Primer第五版上写的并不详细,很多让人困惑的地方没有涉及或者没有讲清楚.于是这几天我 ...
- MongoDB基础教程系列--第八篇 MongoDB 副本集实现复制功能
为什么用复制 为什么要使用复制呢?如果我们的数据库只存在于一台服务器,若这台服务器宕机了,那对于我们数据将会是灾难,当然这只是其中一个原因,若数据量非常大,读写操作势必会影响数据库的性能,这时候复制就 ...
- Apache设置404页面
使用版本:Apache 2.2 1.添加404页面 在所配置网站的根目录添加编辑好的 404.html (页面名字无所谓 比如也可以叫missing.html) 如C:\Program Files\A ...
- git-ftp 用git管理ftp空间
ftp管理不能实现版本控制,而且多电脑工作时,同步很成问题. git-ftp可以完美的解决问题 下面是我的趟坑之路,本机的环境是win10,首先你的机器得装有git. git-ftp的地址https: ...
- Spring aop切面插入事物回滚
<!-- tx标签配置 事物--> <tx:advice id="txadvice" transaction-manager="transactionM ...
- 一个 Vue + Node + MongoDB 博客系统
源码 耗时半载(半个月)的大项目终于完成了.这是一个博客系统,使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB.实现了用户注册.用户登录.博客管理(文章的 ...
- Winform 使用DotNetBar 根据菜单加载TabControl
winform 如何使用TabControl 控件来做winform界面框架? 这样的效果: 首先菜单的窗口展示的承载器为TabControl 控件,这个控件本身包含多页面预览和页面初始化. 如图所示 ...
- cmd中添加snmpd被控
在cmd中添加snmpd被控,减少手动操作步骤. net stop sharedaccess reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\s ...