5.3.5 List集合类的基本运算函数

any()判断集合至少有一个元素

这个函数定义如下:

1. public fun <T> Iterable<T>.any(): Boolean {
2. for (element in this) return true
3. return false
4. }

如果该集合至少有一个元素,返回true,否则返回false。

代码示例:

1. >>> val emptyList = listOf<Int>()
2. >>> emptyList.any()
3. false
4. >>> val list1 = listOf(1)
5. >>> list1.any()
6. true
7. ```#### `any(predicate: (T) -> Boolean)` 判断集合中是否有满足条件的元素

9. 这个函数定义如下:

11. ```kotlin
12. public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {
13. for (element in this) if (predicate(element)) return true
14. return false
15. }

如果该集合中至少有一个元素匹配谓词函数参数predicate: (T) -> Boolean,返回true,否则返回false。

代码示例:

1. >>> val list = listOf(1, 2, 3)
2. >>> list.any() // 至少有1个元素
3. true
4. >>> list.any({it%2==0}) // 元素2满足{it%2==0}
5. true
6. >>> list.any({it>4}) // 没有元素满足{it>4}
7. false
8. ```#### `all(predicate: (T) -> Boolean)` 判断集合中的元素是否都满足条件

10. 函数定义:

12. ```kotlin
13. public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean {
14. for (element in this) if (!predicate(element)) return false
15. return true
16. }

当且仅当该集合中所有元素都满足条件时,返回true;否则都返回false。

代码示例:

1. >>> val list = listOf(0,2,4,6,8)
2. >>> list.all({it%2==0})
3. true
4. >>> list.all({it>2})
5. false
6. ```#### `none() `判断集合无元素

8. 函数定义:

10. ```kotlin
11. public fun <T> Iterable<T>.none(): Boolean {
12. for (element in this) return false
13. return true
14. }

如果该集合没有任何元素,返回true,否则返回false。

代码示例:

1. >>> val list = listOf<Int>()
2. >>> list.none()
3. true
4. ```#### `none(predicate: (T) -> Boolean)`判断集合中所有元素都不满足条件

6. 函数定义:

8. ```kotlin
9. public inline fun <T> Iterable<T>.none(predicate: (T) -> Boolean): Boolean {
10. for (element in this) if (predicate(element)) return false
11. return true
12. }

当且仅当集合中所有元素都不满足条件时返回true,否则返回false。

代码示例:

1. >>> val list = listOf(0,2,4,6,8)
2. >>> list.none({it%2==1})
3. true
4. >>> list.none({it>0})
5. false
6. ```#### `count()` 计算集合中元素的个数

8. 函数定义:

10. ```kotlin
11. public fun <T> Iterable<T>.count(): Int {
12. var count = 0
13. for (element in this) count++
14. return count
15. }

代码示例:

1. >>> val list = listOf(0,2,4,6,8,9)
2. >>> list.count()
3. 6
4. ```#### `count(predicate: (T) -> Boolean)` 计算集合中满足条件的元素的个数

6. 函数定义:

8. ```kotlin
9. public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int {
10. var count = 0
11. for (element in this) if (predicate(element)) count++
12. return count
13. }

代码示例:

1. >>> val list = listOf(0,2,4,6,8,9)
2. >>> list.count()
3. 6
4. >>> list.count({it%2==0})
5. 5
6. ```#### `reduce`从第一项到最后一项进行累计运算

8. 函数定义:

10. ```kotlin
11. public inline fun <S, T: S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S {
12. val iterator = this.iterator()
13. if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.")
14. var accumulator: S = iterator.next()
15. while (iterator.hasNext()) {
16. accumulator = operation(accumulator, iterator.next())
17. }
18. return accumulator
19. }

首先把第一个元素赋值给累加子accumulator,然后逐次向后取元素累加,新值继续赋值给累加子accumulator = operation(accumulator, iterator.next()),以此类推。最后返回累加子的值。

代码示例:

1. >>> val list = listOf(1,2,3,4,5,6,7,8,9)
2. >>> list.reduce({sum, next->sum+next})
3. 45
4. >>> list.reduce({sum, next->sum*next})
5. 362880
6. >>> val list = listOf("a","b","c")
7. >>> list.reduce({total, s->total+s})
8. abc

10. ```#### `reduceRight`从最后一项到第一项进行累计运算

12. 函数定义:

14. ```kotlin
15. public inline fun <S, T: S> List<T>.reduceRight(operation: (T, acc: S) -> S): S {
16. val iterator = listIterator(size)
17. if (!iterator.hasPrevious())
18. throw UnsupportedOperationException("Empty list can't be reduced.")
19. var accumulator: S = iterator.previous()
20. while (iterator.hasPrevious()) {
21. accumulator = operation(iterator.previous(), accumulator)
22. }
23. return accumulator
24. }

从函数的定义accumulator = operation(iterator.previous(), accumulator), 我们可以看出,从右边累计运算的累加子是放在后面的。

代码示例:

1. >>> val list = listOf("a","b","c")
2. >>> list.reduceRight({total, s -> s+total})
3. cba

如果我们位置放错了,会输出下面的结果:

1. >>> list.reduceRight({total, s -> total+s})
2. abc
3. ```#### `fold(initial: R, operation: (acc: R, T) -> R): R` 带初始值的reduce

5. 函数定义:

7. ```kotlin
8. public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {
9. var accumulator = initial
10. for (element in this) accumulator = operation(accumulator, element)
11. return accumulator
12. }

从函数的定义,我们可以看出,fold函数给累加子赋了初始值initial。

代码示例:

1. >>> val list=listOf(1,2,3,4)
2. >>> list.fold(100,{total, next -> next + total})
3. 110

foldRight和reduceRight类似,有初始值。

函数定义:

1. public inline fun <T, R> List<T>.foldRight(initial: R, operation: (T, acc: R) -> R): R {
2. var accumulator = initial
3. if (!isEmpty()) {
4. val iterator = listIterator(size)
5. while (iterator.hasPrevious()) {
6. accumulator = operation(iterator.previous(), accumulator)
7. }
8. }
9. return accumulator
10. }

代码示例:

1. >>> val list = listOf("a","b","c")
2. >>> list.foldRight("xyz",{s, pre -> pre + s})
3. xyzcba
4. ```#### `forEach(action: (T) -> Unit): Unit` 循环遍历元素,元素是it

6. 我们在前文已经讲述,参看5.3.4。

8. 再写个代码示例:

10. ```kotlin
11. >>> val list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
12. >>> list.forEach { value -> if (value > 7) println(value) }
13. 8
14. 9
15. ```#### `forEachIndexed` 带index(下标) 的元素遍历

17. 函数定义:

19. ```kotlin
20. public inline fun <T> Iterable<T>.forEachIndexed(action: (index: Int, T) -> Unit): Unit {
21. var index = 0
22. for (item in this) action(index++, item)
23. }

代码示例:

1. >>> val list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
2. >>> list.forEachIndexed { index, value -> if (value > 8) println("value of index $index is $value, greater than 8") }

4. value of index 9 is 9, greater than 8
5. ```#### max 、min 查询最大、最小的元素,空集则返回null

7. `max`函数定义:

9. ```kotlin
10. public fun <T : Comparable<T>> Iterable<T>.max(): T? {
11. val iterator = iterator()
12. if (!iterator.hasNext()) return null
13. var max = iterator.next()
14. while (iterator.hasNext()) {
15. val e = iterator.next()
16. if (max < e) max = e
17. }
18. return max
19. }

返回集合中最大的元素。

代码示例:

1. >>> val list = listOf(1,2,3)
2. >>> list.max()
3. 3
4. >>> val list = listOf("a","b","c")
5. >>> list.max()
6. c

min函数定义:

1. public fun <T : Comparable<T>> Iterable<T>.min(): T? {
2. val iterator = iterator()
3. if (!iterator.hasNext()) return null
4. var min = iterator.next()
5. while (iterator.hasNext()) {
6. val e = iterator.next()
7. if (min > e) min = e
8. }
9. return min
10. }

返回集合中的最小元素。

代码示例:

1. >>> val list = listOf(1,2,3)
2. >>> list.min()
3. 1
4. >>> val list = listOf("a","b","c")
5. >>> list.min()
6. a

在Kotlin中,字符串的大小比较比较有意思的,我们直接通过代码示例来学习一下:

1. >>> "c" > "a"
2. true
3. >>> "abd" > "abc"
4. true
5. >>> "abd" > "abcd"
6. true
7. >>> "abd" > "abcdefg"
8. true

我们可以看出,字符串的大小比较是按照对应的下标的字符进行比较的。 另外,布尔值的比较是true大于false:

1. >>> true > false
2. true
3. ```#### `maxBy(selector: (T) -> R): T?` 、 `minBy(selector: (T) -> R): T?`获取函数映射结果的最大值、最小值对应的那个元素的值,如果没有则返回null

5. 函数定义:

7. ```kotlin
8. public inline fun <T, R : Comparable<R>> Iterable<T>.maxBy(selector: (T) -> R): T? {
9. val iterator = iterator()
10. if (!iterator.hasNext()) return null
11. var maxElem = iterator.next()
12. var maxValue = selector(maxElem)
13. while (iterator.hasNext()) {
14. val e = iterator.next()
15. val v = selector(e)
16. if (maxValue < v) {
17. maxElem = e
18. maxValue = v
19. }
20. }
21. return maxElem
22. }

也就是说,不直接比较集合元素的大小,而是以集合元素为入参的函数selector: (T) -> R 返回值来比较大小,最后返回此元素的值(注意,不是对应的selector函数的返回值)。有点像数学里的求函数最值问题:

给定函数 y = f(x) , 求max f(x)的x的值。

代码示例:

1. >>> val list = listOf(100,-500,300,200)
2. >>> list.maxBy({it})
3. 300
4. >>> list.maxBy({it*(1-it)})
5. 100
6. >>> list.maxBy({it*it})
7. -500

对应的 minBy 是获取函数映射后返回结果的最小值所对应那个元素的值,如果没有则返回null。

代码示例:

1. >>> val list = listOf(100,-500,300,200)
2. >>> list.minBy({it})
3. -500
4. >>> list.minBy({it*(1-it)})
5. -500
6. >>> list.minBy({it*it})
7. 100
8. ```#### `sumBy(selector: (T) -> Int): Int` 获取函数映射值的总和

10. 函数定义:

12. ```kotlin
13. public inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int {
14. var sum: Int = 0
15. for (element in this) {
16. sum += selector(element)
17. }
18. return sum
19. }

可以看出,这个sumBy函数算子,累加器sum初始值为0,返回值是Int。它的入参selector是一个函数类型(T) -> Int,也就是说这个selector也是返回Int类型的函数。

代码示例:

1. >>> val list = listOf(1,2,3,4)
2. >>> list.sumBy({it})
3. 10
4. >>> list.sumBy({it*it})
5. 30

类型错误反例:

1. >>> val list = listOf("a","b","c")
2. >>> list.sumBy({it})
3. error: type inference failed: inline fun <T> Iterable<T>.sumBy(selector: (T) -> Int): Int
4. cannot be applied to
5. receiver: List<String>  arguments: ((String) -> String)

7. list.sumBy({it})
8. ^
9. error: type mismatch: inferred type is (String) -> String but (String) -> Int was expected
10. list.sumBy({it})
11. ^