测试项目Github地址:

KotlinForJava

前文传送:

Kotlin入门第一课:从对比Java开始

初次尝试用Kotlin实现Android项目

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入门第二课:集合操作的更多相关文章

  1. 数据结构入门第二课(浙大mooc)

    数据结构入门第二课 目录 数据结构入门第二课 引子 多项式的表示 方法1 顺序结构表示多项式各项 方法2 顺序结构表示非零项 方法3 链表结构存储非零项 多项式问题的启示 线性表 线性表的抽象数据类型 ...

  2. Hibernate入门第二课 Hibernate Tools for Eclipse Plugins安装

    Hibernate入门第二课 Hibernate Tools for Eclipse Plugins安装 你们可以直接去,http://blog.csdn.net/wei_chong_chong/ar ...

  3. Kotlin入门第一课:从对比Java开始

    1. 介绍 今年初,甲骨文再次对谷歌所谓的安卓侵权使用Java提起诉讼,要求后者赔偿高达90亿美元.随后便传出谷歌因此计划将主力语言切换到苹果主导的Swift,不过这事后来没了跟进. 但谷歌在这两天的 ...

  4. Kotlin入门(27)文件读写操作

    Java的文件处理用到了io库java.io,该库虽然功能强大,但是与文件内容的交互还得通过输入输出流中转,致使文件读写操作颇为繁琐.因此,开发者通常得自己重新封装一个文件存取的工具类,以便在日常开发 ...

  5. Kotlin入门(4)声明与操作数组

    上一篇文章介绍了基本变量类型在Kotlin中的用法,不过这只针对单个变量,如果要求把一组相同类型的变量排列起来,形成一个变量数组,那又该如何声明和操作呢? 在Java中声明数组,跟在C语言中声明是一样 ...

  6. Spring入门第二课:Spring配置Bean的细节

    1.配置bean的作用域: 通过配置scope属性可以bean的作用域,参数有 prototype.request.session.singleton. 1)singleton为单例,IoC容器只会创 ...

  7. MySQL入门第二天——记录操作与连接查询

    常见SQL语法,请参见w3school:http://www.w3school.com.cn/sql/sql_distinct.asp 易百教程:http://www.yiibai.com/sql/f ...

  8. Spring入门第二课

    看代码 package logan.spring.study; public class HelloWorld { private String name; public void setName2( ...

  9. mysql 第二课 DML操作

    DML 数据操纵语句:INSERT UPDATE DELETE SELECT 主要用来对数据库的数据进行一些操作; DCL 数据定义语句:CREATE ALTER DROP  主要是用在定义或改变表的 ...

随机推荐

  1. Linux开机启动(bootstrap)下

    init process (根据boot loader的选项,Linux此时可以进入单用户模式(single user mode).在此模式下,初始脚本还没有开始执行,我们可以检测并修复计算机可能存在 ...

  2. IOS设备型号(原创)

    以下是我收集的ios目前为止移动设备型号,ipad air不知道,本人没有这款设备,求指导的给个回复,在这谢谢了 ///** ////////////////////   设备类型 字符串   /// ...

  3. 【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图

    标题很难引人入胜,先放个效果图好了 如果图片吸引不了你,那我觉得也就没啥看的了. demo链接: https://win7killer.github.io/can_demo/demo/draw_rol ...

  4. 探讨弹性布局Flexible Box

    虽然Flex布局09年就被W3C所提出,但是目前浏览器支持上还不是很好,网上找的一张图片,仅供参考: 我们先从简单讲起.如果仅仅只想实现一个栅格布局,没必要引入一个复杂的框架(如bootstrap), ...

  5. 【zzulioj 2127】 tmk射气球

    比较简单的题,直接求空间中一个点到直线的距离而已,这道题说了直线和水平的平面 平行,我们可以先求投影到直线的距离,然后再算当前点到直线的距离. Description 有一天TMK在做一个飞艇环游世界 ...

  6. mapTask并行度优化及源码分析

    mapTask并行度的决定机制 一个job的map阶段并行度由客户端在提交job时决定,而客户端对map阶段并行度的规划的基本逻辑为:将待处理数据执行逻辑切片(即按照一个特定切片大小,将待处理数据划分 ...

  7. python之numpy的安装

    这是我第一次写博客,我的第一次打算送给python的numpy库的安装指导,这是我看到一位大神的博客后产生的启发,真是控制不住自己,必须得写一下. 第一次安装numpy浪费了我一个下午,结果还没安装好 ...

  8. 用Web抓包分析工具Livepool 实现本地替换开发

    这是官方的介绍: LivePool 是一个基于 NodeJS,类似 Fiddler 支持抓包和本地替换的 Web 开发调试工具,是 Tencent AlloyTeam 在开发实践过程总结出的一套的便捷 ...

  9. 使用Java POI来选择提取Word文档中的表格信息

    通过使用Java POI来提取Word(1992)文档中的表格信息,其中POI支持不同的ms文档类型,在具体操作中需要注意.本文主要是通过POI来提取微软2003文档中的表格信息,具体code如下(事 ...

  10. mui开发app之html5+,5+Runtime,5+sdk,native.js

    说说几个名词 html5:目前最新的html规范,w3c联盟制定,手机端主要由webkit实现规范,对用户来说就是浏览器实现了它 html5+:所谓"+",扩充了html5原本没有 ...