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 主要是用在定义或改变表的 ...
随机推荐
- 在hive中直接对timestamp类型取max报错
之前直接对timestamp类型做max操作, select id,max(updatetime) updatetime from his.tag group by id; 结果查询的结果有的显示为1 ...
- js实现文本框溢出文字用省略号(...)表示
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 通过php动态传数据到highcharts
1:在平时工作中,在对数据进行展示的时候,是直接通过后台提供的接口来获取json串,用来展示.今天别人问怎么在本地演示一下请求的动态数据. 2:在本地搭建环境,我用的WampServer,下载地址:h ...
- Android 开发之错误整理 [2014-04-28 09:22:28 - XXXX] Unable to resolve target 'android-18'
在开发的时候难免会导入项目,那么怎么经常会遇到这个错误: [2014-04-28 09:22:28 - XXXX] Unable to resolve target 'android-18' targ ...
- Hibernate基础学习(六)—Hibernate二级缓存
一.概述 Session的缓存是一块内存空间,在这个内存空间存放了相互关联的Java对象,这个位于Session缓存内的对象也被称为持久化对象,Session负责根据持久化对象的状态来同步更 ...
- day002-HTML知识点总结:浏览器兼容性之指定IE浏览器使用chrome内核渲染页面
今天再浏览大淘宝首页时,突然看到这么一个东东: ,顿时好费解,莫非万恶的IE浏览器认识到自己以往的罪孽,开始兼容chrome了??! 于是本着不懂就百度的神精,开始纵横于各大铁耙,勃哥,终于找到了许许 ...
- Java实现Android,iOS设备实时监控
Java实现Android设备实时监控 设计思路: 第一,启动一个实时截图线程,负责实时截取Android设备屏幕,保存到本地路径. 第二,在JSP页面,定义一个img对象,实时更换img对象的src ...
- [.NET产品源码保护].NET防止反编译(非混淆加密)
.NET产品源码保护产生的背景: .NET源码加密方案支持C#及VB.NET等语言开发的ASP.NET及WINFORM应用.利用.NET支持托管代码与非托管代码共存的特性,将C#代码经过处理放于非托管 ...
- 简单的留言板(dom+正则练习)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- MySQL中字符串与数字比较的坑
公司项目代码中,某枚举字段数据库表中类型是char(1),在代码中,误以为是TINYINT,所以用数字筛选,后来发现结果不对.发现了一个现象,用数字0筛选会把所有的记录给筛选出来. 经过排查发现是在M ...