一、Kotlin集合介绍
设计初衷
Kotlin
中将集合设计为可变和可读两种,设计的初衷是为了在实际开发过程中数据的行为逻辑更容易让人理解。
如果传递的参数是可变集合,一般表明函数内部涉及到集合修改操作。同理,如果传递只读集合参数,说明函数内部只涉及集合读取操作。
集合分类
Kotlin
集合接口图表如下所示
其中可变集合MutableXXX
与只读集合的关系是继承关系
Iterable
和MutableIterable
接口分别是只读和可变集合的父接口。
Collection
继承Iterable
;List
、Set
接口继承自Collection
;Map
接口是单独的接口,MutableMap
接口是继承自Map
.
Java
中的ArrayList
类和HashSet
类实际上对应Kotlin
中的MutableList
和MutableSet
集合接口的实现类。
二、函数式API操作符分类
这里简单对Kotlin
集合中常见的函数式API操作符进行归纳分类
-
筛选过滤类
主要为
slice
、filter
操作符系列,drop
操作符系列,take
操作符系列,distinct
操作符系列 -
并集类
主要为
any
、all
、count
、none
操作符系列,fold
操作符系列,forEach
操作符系列,max
与min
操作符系列,reduce
操作符系列、sum
操作符系列 -
映射类
主要为
flatMap
系列,groupBy
系列,map
系列 -
元素类
主要为
elementAt
系列,first
系列,find
系列,indexOf
系列,last
系列,single
系列,component
系列 -
排序类
主要为
reverse
、sort
系列 -
生成类
主要为
partition
、plus
系列,zip
系列
三、筛选过滤类操作符
3.1 slice系列
slice(indices: IntRange)
与 slice(indices: Iterable<Int>)
-
基本定义
slice
操作符可以取集合中一部分元素或者某个元素,最后组合成一个新元素slice(indices: IntRange)
:指定切片的起始位置和终止位置,将范围内的元素切出加入到新集合slice(indices: Iterable<Int>)
:指定下标分别切出对应的元素,放入新集合中 -
源码定义与解析
public fun <T> List<T>.slice(indices: IntRange): List<T> { if (indices.isEmpty()) return listOf() return this.subList(indices.start, indices.endInclusive + 1).toList() } public fun <T> List<T>.slice(indices: Iterable<Int>): List<T> { val size = indices.collectionSizeOrDefault(10) if (size == 0) return emptyList() val list = ArrayList<T>(size) for (index in indices) { list.add(get(index)) } return list } 复制代码
slice
函数是List\<T>
的一个扩展函数,最终返回一个list
集合。接收
IntRange
对象的函数拿到对应的start
、end
位置,利用subList
拿到子集合返回接收
Iterable
下标集合函数,内部创建一个新的集合对象,遍历原集合,将下标集合中的元素加入到新创建的集合中,返回这个新集合 -
使用示例
fun main(args: Array<String>) { val numberList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9) val newNumberList1 = numberList.slice(IntRange(3, 6)) print("slice by IntRange: ") newNumberList1.forEach { print("$it ") //打印结果:4 5 6 7 } println() val newNumberList2 = numberList.slice(listOf(1, 3, 7)) print("slice by iterator index: ") newNumberList2.forEach { print("$it ") //打印结果:2 4 8 } } 复制代码
3.2 filter系列
filter(predicate: (T) -> Boolean)
filterTo(destination: C, predicate: (T) -> Boolean)
-
基本定义
根据用户定义的条件筛选集合中的数据,由此产生一个新的集合,该集合是原集合的子集。
-
源码定义与解析
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> { return filterTo(ArrayList<T>(), predicate) } public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C { for (element in this) if (predicate(element)) destination.add(element) return destination } 复制代码
filter()
是一个Iterable/<T>
的扩展函数且是内联函数。filter
内部调用了filterTo
函数,传入新创建的ArrayList
可变集合对象,继续把lambda
表达式作为参数传递到filterTo
函数中,在filterTo
函数实现真正过滤操作。传入的
lambda
表达式predicate
实际上就是外部调用者传入的过滤条件,内部利用一个for
循环进行筛选判断符合lambda
表达式条件的,就添加到新集合对象中,最后返回这个新集合对象。 -
使用示例
filter()
适用于:从一个集合筛选出符合条件的元素,并以一个新集合返回。fun main(args: Array<String>) { val numberList = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val newNumberList = numberList.filter { number -> number % 2 == 0//筛选出偶数 } newNumberList.forEach { print("$it ")} } /******打印结果******/ 0 2 4 6 8 10 复制代码
filterTo()
适用于:从多个集合筛选出符合条件的元素,并最终用一个集合进行收集从每个集合筛选出的元素。fun main(args: Array<String>) { val numberList1 = listOf(23, 65, 14, 57, 99, 123, 26, 15, 88, 37, 56) val numberList2 = listOf(13, 55, 24, 67, 93, 137, 216, 115, 828, 317, 16) val numberList3 = listOf(20, 45, 19, 7, 9, 3, 26, 5, 38, 75, 46) //filterTo的destination是一个可变集合类型,所以这里使用的mutableListOf初始化 val newNumberList = mutableListOf<Int>().apply { numberList1.filterTo(this) { it % 2 == 0 } numberList2.filterTo(this) { it % 2 == 0 } numberList3.filterTo(this) { it % 2 == 0 } } print("从三个集合筛选出的偶数集合: ") newNumberList.forEach { print("$it ") } } /******打印结果******/ 14 26 88 56 24 ...... 复制代码
filterIndexed(predicate: (index: Int, T) -> Boolean)
filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean)
-
基本定义
filterIndexed
与filter
的区别在于其筛选条件的lambda
表达式多暴露了一个参数,即元素在集合中的index
。外部可以拿到这个元素以及这个元素的index
,适合需要集合元素index
参与筛选条件的case
-
源码定义与解析
public inline fun <T> Iterable<T>.filterIndexed(predicate: (index: Int, T) -> Boolean): List<T> { return filterIndexedTo(ArrayList<T>(), predicate) } public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C { forEachIndexed { index, element -> if (predicate(index, element)) destination.add(element) } return destination } public inline fun <T> Iterable<T>.forEachIndexed(action: (index: Int, T) -> Unit): Unit { var index = 0 for (item in this) action(checkIndexOverflow(index++), item) } 复制代码
filterIndexed
实现涉及到filterIndexedTo
、forEachIndexed
。filterIndexed
是一个Iterable\<T>
的扩展函数且是一个内联函数,实现原理与filter
类似,其中index
实际上是forEachIndexed
内部的一个迭代自增计数器,在内部每次迭代,计数器就会自增一次,且把这个index
回调到外部 -
使用场示例
filterIndexed()
适用于:需要集合元素index
参与筛选条件fun main(args: Array<String>) { val numberList = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val newNumberList = numberList.filterIndexed { index, number -> index < 5 && number % 2 == 0 //筛选出集合中前五个元素中是偶数的数 } newNumberList.forEach { print("$it ") } } /******打印结果******/ 0 2 4 复制代码
filterIndexedTo()
适用于:从多个集合筛选出符合条件的元素,筛选条件需要index
,并最终用一个集合进行收集从每个集合筛选出的元素。val numbers: List<Int> = listOf(0, 1, 2, 3, 4, 8, 6) val numbersOnSameIndexAsValue = mutableListOf<Int>() println(numbersOnSameIndexAsValue) // [] numbers.filterIndexedTo(numbersOnSameIndexAsValue) { index, i -> index == i } println(numbersOnSameIndexAsValue) /******打印结果******/ [0, 1, 2, 3, 4, 6] 复制代码
filterIsInstance()
filterIsInstanceTo(destination: C)
-
基本定义
filterIsInstance
操作符:从集合中筛选出instance
某个特定类型元素,并把该元素强转成该类型,最后返回这些元素集合。 -
源码定义与解析
public inline fun <reified R> Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> { return filterIsInstanceTo(ArrayList<R>()) } public inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceTo(destination: C): C { for (element in this) if (element is R) destination.add(element) return destination } 复制代码
filterIsInstance
操作符是一个扩展函数,借助filterIsInstanceTo
实现。通过外部传入的R泛型,创建一个R泛型的
ArrayList
可变集合,用于收集原集合中instance R
类型的元素。filterIsInstanceTo
内部是遍历集合然后利用is判断属于R
类型的元素就加入到集合中,最后返回该集合。 -
使用示例
filterInstance()
适用于:一个抽象类集合中还有多种子类型的元素,可以很方便筛选对应子类型的元素,并组成一个集合返回。abstract class Animal(var name: String, var age: Int){ abstract fun eatFood(): String } class Bird(name: String, age: Int): Animal(name, age){ override fun eatFood() = "bird eat worm" } class Cat(name: String, age: Int) : Animal(name, age) { override fun eatFood() = "Cat eat Fish" } class Dog(name: String, age: Int) : Animal(name, age) { override fun eatFood() = "dog eat bone" } fun main(args: Array<String>) { val animalList: List<Animal> = listOf(Bird(name = "Bird1", age = 12), Cat(name = "Cat1", age = 18), Cat(name = "Cat3", age = 20), Dog(name = "Dog2", age = 8), Cat(name = "Cat2", age = 8), Bird(name = "Bird2", age = 14), Bird(name = "Bird3", age = 16), Dog(name = "Dog1", age = 18) ) //筛选出所有Dog的信息,借助filterIsInstance操作符 animalList.filterIsInstance<Dog>().forEach { println("${it.name} is ${it.age} years old, and ${it.eatFood()}") } } 复制代码
等价于:
//筛选出个所有Dog的信息,借助filter和map操作符 animalList.filter { it is Dog }.map { it as Dog }.forEach { println("${it.name} is ${it.age} years old, and ${it.eatFood()}") } 复制代码
filterInstanceTo
适用于筛选多个集合的情况。
filterNot(predicate: (T) -> Boolean)
filterNotTo(destination: C, predicate: (T) -> Boolean)
-
基本定义
从一个集合筛选出符合条件之外的元素,并以一个新集合返回。它是
filter
操作符取反操作。 -
源码定义与解析
public inline fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T> { return filterNotTo(ArrayList<T>(), predicate) } public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterNotTo(destination: C, predicate: (T) -> Boolean): C { for (element in this) if (!predicate(element)) destination.add(element) return destination } 复制代码
-
使用示例
使用场景就是
filter
使用的取反条件使用,当然你也可以继续使用filter
操作符,并且筛选条件为取反条件。示例参见
filter
操作符
filterNotNull()
filterNotNullTo(destination: C)
-
基本定义
filterNotNull
操作符可以过滤集合中为null
的元素。同理filterNotNullTo
才是真正过滤操作,但是需要从外部传入一个可变集合。 -
源码定义与解析
public fun <T : Any> Iterable<T?>.filterNotNull(): List<T> { return filterNotNullTo(ArrayList<T>()) } public fun <C : MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(destination: C): C { for (element in this) if (element != null) destination.add(element) return destination } 复制代码
filterNotNull
是集合的扩展函数,该集合中的元素是可null
的T泛型,筛选条件即判断是否为null
。filterNotNull
传入一个可变集合,然后在filterNotNullTo
内部判断把null
的元素直接过滤,其他元素就会被加入传入的可变集合中。 -
使用场景与示例
filterNotNull()
适用于: 过滤掉集合中为null
的元素,最后返回一个不含null
的元素集合filterNotNullTo()
适用于: 在外部传入一个可变的集合,然后过滤多个集合中为null
的元素,最后将这些元素放入可变集合中,并返回这个集合。fun main(args: Array<String>) { val animalList: List<Animal?> = listOf(Bird(name = "Bird1", age = 12), Cat(name = "Cat1", age = 18), Cat(name = "Cat3", age = 20), Dog(name = "Dog2", age = 8), null, Bird(name = "Bird2", age = 14), null, Dog(name = "Dog1", age = 18) ) animalList.filterNotNull().forEach { println("${it.name} is ${it.age} years old and it ${it.eatFood()}") } } 复制代码
3.3 drop系列
drop(n: Int)
-
基本定义
根据传入数值n,表示从左到右顺序地删除n个集合中的元素,并返回集合中剩余的元素。
-
源码定义与解析
public fun <T> Iterable<T>.drop(n: Int): List<T> { require(n >= 0) { "Requested element count $n is less than zero." } if (n == 0) return toList() val list: ArrayList<T> if (this is Collection<*>) { val resultSize = size - n if (resultSize <= 0) return emptyList() if (resultSize == 1) return listOf(last()) list = ArrayList<T>(resultSize) if (this is List<T>) { if (this is RandomAccess) { for (index in n until size) list.add(this[index]) } else { for (item in listIterator(n)) list.add(item) } return list } } else { list = ArrayList<T>() } var count = 0 for (item in this) { if (count >= n) list.add(item) else ++count } return list.optimizeReadOnlyList() } 复制代码
-
使用示例
drop
操作符适用于:把集合元素去除一部分,drop
是顺序地删除,n则表示顺序删除几个元素,最后返回剩余元素集合fun main(args: Array<String>) { val numberList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9) numberList.drop(5).forEach { print("$it ") } } /******打印结果******/ 6 7 8 9 复制代码
dropLast(n: Int)
-
基本定义
根据传入数值n,表示从右到左倒序地删除n个集合中的元素,并返回集合中剩余的元素。
-
源码定义与解析
public fun <T> List<T>.dropLast(n: Int): List<T> { require(n >= 0) { "Requested element count $n is less than zero." } return take((size - n).coerceAtLeast(0)) } //这是一个Int类型的扩展函数,用于判断某个值是否大于传入默认最小值,如果大于就直接返回这个值,否则返回这个默认最小值 public fun Int.coerceAtLeast(minimumValue: Int): Int { return if (this < minimumValue) minimumValue else this } public fun <T> Iterable<T>.take(n: Int): List<T> { require(n >= 0) { "Requested element count $n is less than zero." } if (n == 0) return emptyList() if (this is Collection<T>) { if (n >= size) return toList() if (n == 1) return listOf(first()) } var count = 0 val list = ArrayList<T>(n) for (item in this) { list.add(item) if (++count == n) break } return list.optimizeReadOnlyList() } 复制代码
这是一个
List/<T>
的扩展函数,涉及到coerceAtLeast
和take
,其是通过调用take
来实现take
是Iterable/<T>
的扩展函数 -
使用示例
dropLast
操作符使用场景与drop
相反,整体作用与其相似fun main(args: Array<String>) { val strList = listOf("kotlin", "java", "javaScript", "C", "C++", "python", "Swift", "Go", "Scala") strList.dropLast(3).forEach { print("$it ") } } /******打印结果******/ kotlin java javaScript C C++ paython 复制代码
dropWhile(predicate: (T) -> Boolean)
-
基本定义
从集合的第一项开始去掉满足条件元素,这样操作一直持续到出现第一个不满足条件元素出现为止,返回剩余元素(可能剩余元素有满足条件的元素)
-
源码定义与解析
public inline fun <T> Iterable<T>.dropWhile(predicate: (T) -> Boolean): List<T> { var yielding = false //初始化标志位 val list = ArrayList<T>() for (item in this) //遍历集合 if (yielding) list.add(item) else if (!predicate(item)) { //判断不符合外部传入条件 list.add(item) yielding = true } return list } 复制代码
-
使用示例
dropWhile
操作符适用于:去掉集合中前半部分具有相同特征的元素场景。fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx","python", "Swift", "Go", "Scala") strList.dropWhile { it.startsWith("java") }.forEach { print("$it ") } } /******打印结果******/ kotlin C C++ javaFx python Swift Go Scala 复制代码
dropLastWhile(predicate: (T) -> Boolean)
-
基本定义
从集合的最后一项开始去掉满足条件元素,这样操作一直持续到出现第一个不满足条件元素出现为止,返回剩余元素(可能剩余元素有满足条件的元素)
-
源码定义与解析
public inline fun <T> List<T>.dropLastWhile(predicate: (T) -> Boolean): List<T> { if (!isEmpty()) { val iterator = listIterator(size) //表示从原集合尾部开始向头部迭代 while (iterator.hasPrevious()) { //元素存在上一个元素 if (!predicate(iterator.previous())) { //直到出现上一个元素不符合条件,才开始取相应后续元素,加入到新集合中 return take(iterator.nextIndex() + 1) } } } return emptyList() } 复制代码
-
使用示例
dropLastWhile
操作符使用场景与dropWhile
类似,不过删除元素顺序不一样fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.dropLastWhile { it.startsWith("S") }.forEach { print("$it ") } } /******打印结果******/ java javaScript kotlin C C++ javaFx python Go 复制代码
3.4 take系列
take(n: Int)
-
基本定义
从原集合的第一项开始顺序取集合的元素,取n个元素,最后返回取出这些元素的集合。换句话说就是取集合前n个元素组成新的集合返回。
-
源码定义与解析
public fun <T> Iterable<T>.take(n: Int): List<T> { require(n >= 0) { "Requested element count $n is less than zero." } if (n == 0) return emptyList() //取0个元素集合,返回空集合 if (this is Collection<T>) { if (n >= size) return toList() //如果取元素集合大小大于或等于原集合大小,就直接返回原集合 if (n == 1) return listOf(first()) //取一个元素,就是集合的first() } var count = 0 val list = ArrayList<T>(n) for (item in this) { //遍历集合 list.add(item) if (++count == n) break } return list.optimizeReadOnlyList() } 复制代码
-
使用示例
take
操作符适用于:顺序从第一项开始取集合中的子集fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.take(2).forEach { print("$it ") } } /*******打印结果******/ java javaScript 复制代码
takeLast(n: Int)
-
基本定义
从原集合的最后一项开始倒序取集合的元素,取n个元素,最后返回取出这些元素的集合。
-
源码定义与解析
public fun <T> List<T>.takeLast(n: Int): List<T> { require(n >= 0) { "Requested element count $n is less than zero." } if (n == 0) return emptyList() //取0个元素,返回空集合 val size = size if (n >= size) return toList() if (n == 1) return listOf(last()) val list = ArrayList<T>(n) if (this is RandomAccess) {//RandomAccess是一个集合标记接口,如果集合类是RandomAccess的实现,则尽量用index下标 来遍历而不要用Iterator迭代器来遍历,在效率上要差一些。反过来,如果List是Sequence List,则最好用迭代器来进行迭代。 for (index in size - n until size) list.add(this[index]) } else { for (item in listIterator(size - n)) list.add(item) } return list } 复制代码
-
使用示例
takeLast
操作符适用于:倒序从最后一项开始取集合中子集合fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.takeLast(2).forEach { print("$it ") } } /******打印结果******/ Swift Scala 复制代码
takeLastWhile(predicate: (T) -> Boolean)
-
基本定义
从集合的最后一项开始取出满足条件元素,这样操作一直持续到出现第一个不满足条件元素出现为止,暂停取元素,返回取出元素的集合。
-
源码定义与解析
public inline fun <T> List<T>.takeLastWhile(predicate: (T) -> Boolean): List<T> { if (isEmpty()) return emptyList() val iterator = listIterator(size) //表示从集合index = size开始迭代,那么size - 1也是最后一个元素,也即是迭代器的previous,也就是从集合尾部开始向头部迭代 while (iterator.hasPrevious()) { if (!predicate(iterator.previous())) { //也是从最后一项开始遇到第一个不符合条件的元素,不进入以下操作 iterator.next() val expectedSize = size - iterator.nextIndex() //符合条件元素集合的expectedSize等于原集合size与当前下一个元素的index的差值 if (expectedSize == 0) return emptyList() return ArrayList<T>(expectedSize).apply { //拿到符合条件元素集合size,创建expectedSize大小新集合,并把迭代器中的元素遍历加入到新集合中 while (iterator.hasNext()) add(iterator.next()) } } } return toList() } 复制代码
-
使用示例
takeLastWhile
操作符适用于:取出集合中后半部分具有相同特征的元素场景fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.takeLastWhile { it.startsWith("S") }.forEach { print("$it ") } } /******打印结果******/ Swift Scala 复制代码
takeWhile(predicate: (T) -> Boolean)
-
基本定义
从集合的第一项开始取出满足条件元素,这样操作一直持续到出现第一个不满足条件元素出现为止,暂停取元素,返回取出元素的集合。
-
源码定义与解析
public inline fun <T> Iterable<T>.takeWhile(predicate: (T) -> Boolean): List<T> { val list = ArrayList<T>() for (item in this) { if (!predicate(item)) //不符合传入条件就跳出循环 break list.add(item) } return list } 复制代码
-
使用示例
takeshiWhile
操作符适用于:取出集合中前半部分具有相同特征的元素场景fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.takeWhile { it.startsWith("java") }.forEach { print("$it ") } } /******打印结果******/ java javaScript 复制代码
3.5 distinct系列
distinct()
-
基本定义
去除集合中的重复元素
-
源码定义与解析
public fun <T> Iterable<T>.distinct(): List<T> { return this.toMutableSet().toList() } public fun <T> Iterable<T>.toMutableSet(): MutableSet<T> { return when (this) { is Collection<T> -> LinkedHashSet(this) else -> toCollection(LinkedHashSet<T>()) } } 复制代码
-
使用示例
distinct
操作符适用于:去除集合中的重复元素fun main(args: Array<String>) { val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") val numberList = listOf("111","222","333","444","555","111","333") print(numberList.distinct()) } /******打印结果******/ [111, 222, 333, 444, 555] 复制代码
distinctBy(selector: (T) -> K)
-
基本定义
根据操作元素后的结果去除重复元素
-
源码定义与解析
public inline fun <T, K> Iterable<T>.distinctBy(selector: (T) -> K): List<T> { val set = HashSet<K>() val list = ArrayList<T>() for (e in this) { val key = selector(e) if (set.add(key)) list.add(e) } return list } 复制代码
-
使用示例
distinctBy
操作符适用于:根据元素操作的结果进行集合元素去重fun main(args: Array<String>) { val strList = listOf<String>("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") val numberList = listOf("111","212","332","444","555","111") print(numberList.distinctBy { it.toInt() % 111 }) } /******打印结果******/ [111, 212, 332] 复制代码
四、并集类操作符
4.1 any、all、count、none系列
any()
-
基本定义
判断是不是一个集合,若是,则再判断集合是否为空。若为空则返回
false
,反之返回true
。若不是集合,则返回hasNext
-
源码定义与解析
public fun <T> Iterable<T>.any(): Boolean { if (this is Collection) return !isEmpty() return iterator().hasNext() } 复制代码
-
使用示例
any()
操作符适用于:判断是否是一个集合fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") print(strList.any()) } /*******打印结果*******/ true 复制代码
any(predicate: (T) -> Boolean)
-
基本定义
判断集合中是否存在满足条件的元素。若存在则返回
true
,反之返回false
-
源码定义与解析
public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean { if (this is Collection && isEmpty()) return false for (element in this) if (predicate(element)) return true return false } 复制代码
-
使用示例
any{}
操作符适用于:判断一个集合是否存在满足条件的元素fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") print(strList.any { it.startsWith("py") }) } 复制代码
all(predicate: (T) -> Boolean)
-
基本定义
判断集合中的所有元素是否都满足条件。若是则返回
true
,反之则返回false
-
源码定义与解析
public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean { if (this is Collection && isEmpty()) return true for (element in this) if (!predicate(element)) return false return true } 复制代码
实现原理与any类似
-
使用示例
all
操作符适用场景与any
相反,判断集合中所有元素是否都满足条件fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") print(strList.all { it.startsWith("py") }) } /******打印结果******/ false 复制代码
count()
count(predicate: (T) -> Boolean)
-
基本定义
返回集合中的元素个数或查询集合中满足条件的元素个数
-
源码定义与解析
public fun <T> Iterable<T>.count(): Int { if (this is Collection) return size var count = 0 for (element in this) checkCountOverflow(++count) return count } public inline fun <T> Collection<T>.count(): Int { return size } public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int { if (this is Collection && isEmpty()) return 0 var count = 0 for (element in this) if (predicate(element)) checkCountOverflow(++count) return count } 复制代码
-
使用示例
count
操作符适用于:查询集合元素个数或集合中满足条件的元素个数fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.count()) println(strList.count { it.startsWith("java") }) } /******打印结果******/ 10 3 复制代码
none()
none(predicate: (T) -> Boolean)
-
基本定义
如果一个集合是空集合,返回
true
或者集合中没有满足条件的元素,则返回true
-
源码定义与解析
public fun <T> Iterable<T>.none(): Boolean { if (this is Collection) return isEmpty() return !iterator().hasNext() } public inline fun <T> Iterable<T>.none(predicate: (T) -> Boolean): Boolean { if (this is Collection && isEmpty()) return true for (element in this) if (predicate(element)) return false return true } 复制代码
实现方式与
any
类似 -
使用示例
none
操作符适用场景与any
相反fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.none()) println(strList.none { it.startsWith("java") }) } 复制代码
4.2 fold系列
fold(initial: R, operation: (acc: R, T) -> R)
-
基本定义
在一个初始值的基础上从第一项到最后一项通过一个函数累计所有的元素。
-
源码定义与解析
public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R { var accumulator = initial for (element in this) accumulator = operation(accumulator, element) return accumulator } 复制代码
-
使用示例
fold
操作符适用于:给定初始值,按照某个函数对集合中的每个元素进行累计fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.fold("php"){result, element -> "$result$element"}) } /******打印结果******/ phpjavajavaScriptkotlinCC++javaFxpythonGoSwiftScala 复制代码
foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R)
-
基本定义
在一个初始值的基础上,从第一项到最后一项通过一个函数累计所有的元素,该函数的参数可以包含元素索引
-
源码定义与解析
public inline fun <T, R> Iterable<T>.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R { var index = 0 var accumulator = initial for (element in this) accumulator = operation(checkIndexOverflow(index++), accumulator, element) return accumulator } 复制代码
-
使用示例
foldIndexed
操作符适用场景与fold
相似fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.foldIndexed("php"){index,result, element -> "$result $element$index"}) } /******打印结果******/ php java0 javaScript1 kotlin2 C3 C++4 javaFx5 python6 Go7 Swift8 Scala9 复制代码
foldRight(initial: R, operation: (T, acc: R) -> R)
-
基本定义
在一个初始值的基础上,从最后项到第一项通过一个函数累计所有的元素,与fold类似
-
源码定义与解析
public inline fun <T, R> List<T>.foldRight(initial: R, operation: (T, acc: R) -> R): R { var accumulator = initial if (!isEmpty()) { val iterator = listIterator(size) while (iterator.hasPrevious()) { accumulator = operation(iterator.previous(), accumulator) } } return accumulator } 复制代码
-
使用示例
foldRight
操作符适用场景与fold类似,不过是从最后一项开始累计fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.foldRight("php"){element, result -> "$result $element"}) } /******打印结果******/ php Scala Swift Go python javaFx C++ C kotlin javaScript java 复制代码
foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R)
-
基本定义
在一个初始值的基础上,从最后一项到第一项通过一个函数累计所有的元素,该函数的参数可以包含元素索引
-
源码定义与解析
public inline fun <T, R> List<T>.foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R): R { var accumulator = initial if (!isEmpty()) { val iterator = listIterator(size) while (iterator.hasPrevious()) { val index = iterator.previousIndex() accumulator = operation(index, iterator.previous(), accumulator) } } return accumulator } 复制代码
-
使用示例
foldRightIndexed
操作符使用场景与foldIndexed
类似fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.foldRightIndexed("php"){index,element, result -> "$result $element$index"}) } /******打印结果******/ php Scala9 Swift8 Go7 python6 javaFx5 C++4 C3 kotlin2 javaScript1 java0 复制代码
4.3 forEach系列
forEach(action: (T) -> Unit)
-
基本定义
遍历元素
-
源码定义与解析
/** * Performs the given [action] on each element. */ @kotlin.internal.HidesMembers public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit { for (element in this) action(element) } 复制代码
-
使用示例
forEach
操作符适用于:集合元素的遍历操作符fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.forEach{ print("$it ") } } /******打印结果******/ java javaScript kotlin C C++ javaFx python Go Swift Scala 复制代码
forEachIndexed(action: (index: Int, T) -> Unit)
-
基本定义
遍历元素,可获得集合中元素的下标
-
源码定义与解析
/** * Performs the given [action] on each element, providing sequential index with the element. * @param [action] function that takes the index of an element and the element itself * and performs the desired action on the element. */ public inline fun <T> Iterable<T>.forEachIndexed(action: (index: Int, T) -> Unit): Unit { var index = 0 for (item in this) action(checkIndexOverflow(index++), item) } 复制代码
-
使用示例
forEachIndexed
操作符适用于:集合中带元素下标的遍历操作fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") strList.forEachIndexed { index, s -> print("$s$index ") } } /******打印结果******/ java0 javaScript1 kotlin2 C3 C++4 javaFx5 python6 Go7 Swift8 Scala9 复制代码
4.4 max、min系列
max()
-
基本定义
获取集合中最大的元素,若为空元素集合,则返回
null
-
源码定义与解析
/** * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. */ @SinceKotlin("1.1") public fun Iterable<Float>.max(): Float? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() if (max.isNaN()) return max while (iterator.hasNext()) { val e = iterator.next() if (e.isNaN()) return e if (max < e) max = e } return max } @SinceKotlin("1.1") public fun Iterable<Double>.max(): Double? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() if (max.isNaN()) return max while (iterator.hasNext()) { val e = iterator.next() if (e.isNaN()) return e if (max < e) max = e } return max } public fun <T : Comparable<T>> Iterable<T>.max(): T? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() while (iterator.hasNext()) { val e = iterator.next() if (max < e) max = e } return max } 复制代码
-
使用示例
max
操作符适用于:获取集合中最大的元素,若为空元素集合,则返回null
fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.max()) } 复制代码
maxBy(selector: (T) -> R)
-
基本定义
获取方法处理后返回结果最大值对应那个元素的初始值,如果没有则返回
-
源码定义与解析
/** * Returns the first element yielding the largest value of the given function or `null` if there are no elements. * * @sample samples.collections.Collections.Aggregates.maxBy */ public inline fun <T, R : Comparable<R>> Iterable<T>.maxBy(selector: (T) -> R): T? { val iterator = iterator() if (!iterator.hasNext()) return null var maxElem = iterator.next() if (!iterator.hasNext()) return maxElem var maxValue = selector(maxElem) do { val e = iterator.next() val v = selector(e) if (maxValue < v) { maxElem = e maxValue = v } } while (iterator.hasNext()) return maxElem } 复制代码
-
使用示例
maxBy
操作符适用于:根据给定的函数返回最大的一项,如果没有则返回null
fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") println(strList.maxBy { "${it}kotlin" }) } /******打印结果******/ python 复制代码
maxWith(comparator: Comparator<in T>)
-
基本定义
接受一个
Comparator
对象并且根据此Comparator
对象返回最大元素 -
源码定义与解析
/** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. */ public fun <T> Iterable<T>.maxWith(comparator: Comparator<in T>): T? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() while (iterator.hasNext()) { val e = iterator.next() if (comparator.compare(max, e) < 0) max = e } return max } 复制代码
-
使用示例
maxWith
操作符适用于:接受一个Comparator
对象并且根据此Comparator
对象返回最大元素fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") print(strList.maxWith(compareBy{it.length})) } /******打印结果******/ javaScript 复制代码
min
操作符
min
操作符作用与max
相反,包括minBy
和minWith
4.5 reduce系列
reduce(operation: (acc: S, T) -> S)
-
基本定义
从集合中的第一项到最后一项的累计操作,与
fold
操作符的区别是没有初始值 -
源码定义与解析
public inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S { val iterator = this.iterator() if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.") var accumulator: S = iterator.next() while (iterator.hasNext()) { accumulator = operation(accumulator, iterator.next()) } return accumulator } 复制代码
-
使用示例
reduce
操作符适用于:按照某个函数对集合中的每个元素进行累计fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") print(strList.reduce{result, element -> "$result $element"}) } /******打印结果******/ java javaScript kotlin C C++ javaFx python Go Swift Scala 复制代码
备注:
其中reduceIndexed
,reduceRight
,reduceRightIndexed
操作符都与前述的fold
相关操作符类似,只是没有初始值
reduceOrNull(operation: (acc: S, T) -> S)
-
基本定义
从集合中的第一项到最后一项的累计操作,如果集合为空,返回
null
-
源码定义与解析
/** * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. Returns null if the collection is empty. * * @sample samples.collections.Collections.Aggregates.reduceOrNull */ @SinceKotlin("1.3") @ExperimentalStdlibApi public inline fun <S, T : S> Iterable<T>.reduceOrNull(operation: (acc: S, T) -> S): S? { val iterator = this.iterator() if (!iterator.hasNext()) return null //集合为空,返回null var accumulator: S = iterator.next() while (iterator.hasNext()) { accumulator = operation(accumulator, iterator.next()) } return accumulator } 复制代码
-
使用示例
reduceOrNull
操作符适用于:集合元素的累计操作,且集合可能为null
的情况@ExperimentalStdlibApi fun main(args: Array<String>) { val strList = listOf("java", "javaScript", "kotlin", "C", "C++", "javaFx", "python","Go", "Swift", "Scala") print(strList.reduceOrNull{result, element -> "$result $element"}) } 复制代码
备注:
reduceRightOrNull
操作符作用等价于reduceRight
,不同的是当集合为空,返回null
4.6 sum系列
sum()
-
基本定义
计算出集合元素累加的结果
-
源码定义与解析
/** * Returns the sum of all elements in the collection. */ @kotlin.jvm.JvmName("sumOfByte") public fun Iterable<Byte>.sum(): Int { var sum: Int = 0 for (element in this) { sum += element } return sum } @kotlin.jvm.JvmName("sumOfLong") public fun Iterable<Long>.sum(): Long { var sum: Long = 0L for (element in this) { sum += element } return sum } //....... 复制代码
-
使用示例
sum
操作符适用于:计算集合中所有元素累加的结果fun main(args: Array<String>) { val intList = listOf(1,2,3,4,5,6,7,8,9,10) print(intList.sum()) } /******打印结果******/ 55 复制代码
sumBy(selector: (T) -> Int)
-
基本定义
返回所有每一项通过函数转换之后的数据的总和。
-
源码定义与解析
/** * Returns the sum of all values produced by [selector] function applied to each element in the collection. */ public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int { var sum: Int = 0 for (element in this) { sum += selector(element) } return sum } 复制代码
-
使用示例
sumBy
操作符适用于:计算集合所有元素通过某个函数转换后数据之和fun main(args: Array<String>) { val intList = listOf(1,2,3,4,5,6,7,8,9,10) print(intList.sumBy { it * 2 }) } /******打印结果******/ 110 复制代码
-
备注
sumByDouble
操作符与sumBy
功能一致,只不过其对应double
数据操作