大部分业务代码,都在处理数据!所以,高效很重要!!

开发 开发工具
在日常编写业务代码的时候,大部分代码其实就是在处理数据、展示数据,这些操作占用了我们大量的编码时间。

 [[260740]]

一、序

在日常编写业务代码的时候,大部分代码其实就是在处理数据、展示数据,这些操作占用了我们大量的编码时间。

比较常见的,从某个集合中找到满足某个限制条件的数据。最简单的方法就是利用循环来遍历数据集合,找到我们需要的数据。

  1. fun findFive() { 
  2.     val list = arrayListOf(1, 2, 3, 4, 5, 6, 7) 
  3.     val findList = mutableListOf<Int>() 
  4.     for (i in list) { 
  5.         if (i > 5) { 
  6.             findList.add(i) 
  7.         } 
  8.     } 
  9.     // findList 

大部分数据集合的操作,我们都可以通过循环来解决,针对一些更复杂的操作,例如从两个集合中找出交集集合,可以通过两层嵌套循环解决。

除了用粗暴的循环解决问题之外,我们还可以利用 Kotlin 对集合封装的一些高阶函数,让我们对集合的处理,更得心应手。

上面例子中的需求,用 Kotlin 集合的高阶函数,一个方法就可以解决。

  1. val findList = list.filter { it > 5 } 

集合的高阶函数,还有很多更巧妙的使用方式。

本文就从业务场景出发,讲解 Kotlin 中与集合相关的一些高阶函数的使用和场景。

二、集合的高阶函数

Kotlin 原生就支持 Lambda 表达式,高阶函数中都可以基于 Lambda 来实现的。

假如我们需要实现一个公司内部的员工管理系统,那我们首先定义一个员工类(EmployeModel)。

  1. data class EmployeModel(var id: Long, // 员工 ID 
  2.                         var name: String,// 姓名 
  3.                         var age: Int,// 年龄 
  4.                         var department: String,// 部门 
  5.                         var salary: Int // 薪水 
  6. ) { 
  7.  
  8. // var list = arrayListOf(EmployeModel(...),...) 

接下来我们就围绕这个员工类,实现各种必要的需求。

2.1 数据筛选

需求:从给定的员工列表中,筛选出月薪大于 2w 的所有员工。

正如前文中举例的样子,对于数据筛选,可以使用 .filter() 方法,此方法接受一个 Boolean 类型的条件,它会返回所有满足此条件的数据集合,最终其实返回的依然是一个 List。

  1. var findList = list.filter {it.salary > 20000} 

.filter() 方法内不是其实也是用 for 循环来实现的,没有什么高深的。而除了filter() 之外,Kotlin 还提供了带上一些特殊条件的过滤器。

例如:

  • filterIndexed,带 Index 的过滤器。
  • filterNot,过滤所有不满足条件的数据。

这里就不展开了。

2.2 数据排序

需求:将给定的员工列表,根据员工的薪酬进行排序。

通过 sortedBy() 方法,指定排序依据,它会根据指定的数值,进行自然顺序排序。

  1. var findList = list.sortedBy{it.salary} 

sortedBy() 方法为顺序排序,如果想要逆序排序,可以使用 sortedByDescending()方法。

需要注意的是,除了 sortedBy() 之外,配套的还有 sortBy() 和sortByDescending() 方法,这两套方法的区别在于操作的集合以及返回值是什么。

在 Kotlin 中,所有的集合可以分为可变集合和不可变集合,sortBy/sortByDescending 方法,只能作用在可变集合上,它返回的是一个 Unit 类型的对象,会在集合上进行自排序。而 sortBy() 方法会返回一个排序好的新集合。

2.3 集合切片

需求:将给定的员工列表,只显示前 100 位员工。

如果想获取某个集合中前 N 个员工,可以使用 take() 方法。

  1. var findList = list.take(100) 

和 take() 取前 N 个员工类似,还可以使用 takeLast() 方法获取末尾 N 个员工。

更灵活的切片,例如取第 10~20 的员工,就需要用到 slice() 方法,如果想要截取连续的一段数据,可以使用 IntRange 类来指定。

  1. var findList = list.slice(IntRange(10,20)) 

slice() 方法还支持直接指定集合的下标,来获取不连续的数据,例如选取排名第 1、10、25 位员工。

  1. var findList = list.slice(arrayListOf(1, 10, 15)) 

2.4 集合变换

需求:要调薪了,准备将一批员工涨薪 20%。那就需要批量上报一批员工信息,和服务端商量,只需要上报这一批调薪的员工 ID 即可。

原本我们有一个员工类的集合 List list,但是这个集合里都是一个个员工的对象。在上报之前,我们需要将他们转换成 List

这里就可以用到 map() 方法,它可以对集合中的数据做一次变换。

  1. var findList = list.map { it.id } 

map() 原本是不带 index 的,如果对 index 有需求,可以使用 mapIndexed()方法。

map() 代表了一种一对一的变换关系。如果想做到一对多,可以使用 flatMap()方法,flatMap() 可以将每个元素变换为一个新的集合,再将其平铺成一个集合。

2.5 数据分组

需求:将所有的员工,用年龄以 20 岁为界限进行分组。

这种两分的分组,可以使用 partition() 方法,它需要制定一个分组的条件,以 Boolean 类型区分,最终返回一个 Pair 对象,Pair.first 就是满足条件的集合,Pair.second 则是不满足条件的集合。

  1. var findList = list.partition { it.age > 20 } 
  2. findList.first.forEach{ 
  3.     Log.i("cxmyDev","${it.name} 大于 20"); 
  4. findList.second.forEach{ 
  5.     Log.i("cxmyDev","${it.name} 小于或等于 20"); 

此时需求又变了,要根据部门来分组,公司的部门可不止两个。针对这种情况,可以通过 groupBy() 方法进行分组。

  1. var findList = list.groupBy { it.department } 

groupBy() 方法会返回一个 Map

2.6 其他操作

前面介绍的这些针对 Kotlin 集合的高阶函数,基本上满足我对集合的大部分操作。当然,Kotlin 还有一些更丰富的高阶函数,有兴趣可以直接查看 _Collections.kt 源码。

高阶函数之所以强大,更多的是因为支持链式调用,我们可以通过一个很清晰代码结构,就实现我们对集合的复杂需求。

我拍脑袋举个例子,取员工集合里,A 部门的员工,根据员工 ID 排序后,取前 100 号员工的 ID 进行上报。

  1. var findList = list.filter { 
  2.     "A".equals(it.department) 
  3. }.sortedBy { 
  4.     it.id 
  5. }.map { 
  6.     it.id 
  7. }.take(100) 

这样一个复杂的集合操作,在 Kotlin 的高阶函数中,只需要一组链式调用即可实现。

另外需要注意的是,高阶函数中很多方法,都不是线程安全的,所以在使用的时候,需要考虑多线程场景下的同步问题。

三、小结时刻

本文介绍了一些比较常用的集合操作函数,随着 Kotlin 版本的升级,还有会更多的高阶函数添加进来,更多细节可以阅读源码或者参考 kotlin.collections 文档。

【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】

 

戳这里,看该作者更多好文

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2016-10-26 10:23:42

2019-06-12 10:35:49

程序员高效工具开源

2015-08-04 09:56:48

2010-11-18 12:44:25

LibreOffice

2018-08-31 07:33:58

2014-09-16 11:31:44

移动应用数据安全个人隐私

2016-12-12 18:45:08

Data Mining大数据

2018-11-25 21:53:10

人工智能AI开发者

2018-09-17 15:09:28

区块链去中心化互联网

2010-08-19 10:47:59

诺基亚Ovi永久免费

2021-04-06 15:20:05

编程语言JavaIT

2013-09-16 15:00:15

2021-08-06 17:44:45

云安全云计算网络安全

2011-11-09 09:59:21

云计算IT管理

2020-02-06 13:43:35

微软WindowsWindows 10

2011-05-04 16:55:42

2012-11-23 22:47:36

2011-04-06 16:41:29

网段

2009-05-07 10:09:40

微软裁员招聘

2020-01-08 10:51:24

5G网络安全通信
点赞
收藏

51CTO技术栈公众号