5.3.6 过滤操作函数

take(n: Int): List<T> 挑出该集合前n个元素的子集合

函数定义:

  1. public fun <T> Iterable<T>.take(n: Int): List<T> {
  2. require(n >= 0) { "Requested element count $n is less than zero." }
  3. if (n == 0) return emptyList()
  4. if (this is Collection<T>) {
  5. if (n >= size) return toList()
  6. if (n == 1) return listOf(first())
  7. }
  8. var count = 0
  9. val list = ArrayList<T>(n)
  10. for (item in this) {
  11. if (count++ == n)
  12. break
  13. list.add(item)
  14. }
  15. return list.optimizeReadOnlyList()
  16. }

如果n等于0,返回空集;如果n大于集合size,返回该集合。

代码示例:

  1. >>> val list = listOf("a","b","c")
  2. >>> list
  3. [a, b, c]
  4. >>> list.take(2)
  5. [a, b]
  6. >>> list.take(10)
  7. [a, b, c]
  8. >>> list.take(0)
  9. []
  10. ```#### `takeWhile(predicate: (T) -> Boolean): List<T>` 挑出满足条件的元素的子集合
  11. 函数定义:
  12. ```kotlin
  13. public inline fun <T> Iterable<T>.takeWhile(predicate: (T) -> Boolean): List<T> {
  14. val list = ArrayList<T>()
  15. for (item in this) {
  16. if (!predicate(item))
  17. break
  18. list.add(item)
  19. }
  20. return list
  21. }

从第一个元素开始,判断是否满足predicate为true,如果满足条件的元素就丢到返回ArrayList中。只要遇到任何一个元素不满足条件,就结束循环,返回list 。

代码示例:

  1. >>> val list = listOf(1,2,4,6,8,9)
  2. >>> list.takeWhile({it%2==0})
  3. []
  4. >>> list.takeWhile({it%2==1})
  5. [1]
  6. >>> val list = listOf(2,4,6,8,9,11,12,16)
  7. >>> list.takeWhile({it%2==0})
  8. [2, 4, 6, 8]
  9. ```#### `takeLast` 挑出后n个元素的子集合
  10. 函数定义:
  11. ```kotlin
  12. public fun <T> List<T>.takeLast(n: Int): List<T> {
  13. require(n >= 0) { "Requested element count $n is less than zero." }
  14. if (n == 0) return emptyList()
  15. val size = size
  16. if (n >= size) return toList()
  17. if (n == 1) return listOf(last())
  18. val list = ArrayList<T>(n)
  19. if (this is RandomAccess) {
  20. for (index in size - n .. size - 1)
  21. list.add(this[index])
  22. } else {
  23. for (item in listIterator(n))
  24. list.add(item)
  25. }
  26. return list
  27. }

从集合倒数n个元素起,取出到最后一个元素的子集合。如果传入0,返回空集。如果传入n大于集合size,返回整个集合。如果传入负数,直接抛出IllegalArgumentException。

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.takeLast(0)
  3. []
  4. >>> list.takeLast(3)
  5. [11, 12, 16]
  6. >>> list.takeLast(100)
  7. [2, 4, 6, 8, 9, 11, 12, 16]
  8. >>> list.takeLast(-1)
  9. java.lang.IllegalArgumentException: Requested element count -1 is less than zero.
  10. at kotlin.collections.CollectionsKt___CollectionsKt.takeLast(_Collections.kt:734)
  11. ```#### `takeLastWhile(predicate: (T) -> Boolean)` 从最后开始挑出满足条件元素的子集合
  12. 函数定义:
  13. ```kotlin
  14. public inline fun <T> List<T>.takeLastWhile(predicate: (T) -> Boolean): List<T> {
  15. if (isEmpty())
  16. return emptyList()
  17. val iterator = listIterator(size)
  18. while (iterator.hasPrevious()) {
  19. if (!predicate(iterator.previous())) {
  20. iterator.next()
  21. val expectedSize = size - iterator.nextIndex()
  22. if (expectedSize == 0) return emptyList()
  23. return ArrayList<T>(expectedSize).apply {
  24. while (iterator.hasNext())
  25. add(iterator.next())
  26. }
  27. }
  28. }
  29. return toList()
  30. }

反方向取满足条件的元素,遇到不满足的元素,直接终止循环,并返回子集合。

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.takeLastWhile({it%2==0})
  3. [12, 16]
  4. ```#### `drop(n: Int)` 去除前n个元素返回剩下的元素的子集合
  5. 函数定义:
  6. ```kotlin
  7. public fun <T> Iterable<T>.drop(n: Int): List<T> {
  8. require(n >= 0) { "Requested element count $n is less than zero." }
  9. if (n == 0) return toList()
  10. val list: ArrayList<T>
  11. if (this is Collection<*>) {
  12. val resultSize = size - n
  13. if (resultSize <= 0)
  14. return emptyList()
  15. if (resultSize == 1)
  16. return listOf(last())
  17. list = ArrayList<T>(resultSize)
  18. if (this is List<T>) {
  19. if (this is RandomAccess) {
  20. for (index in n..size - 1)
  21. list.add(this[index])
  22. } else {
  23. for (item in listIterator(n))
  24. list.add(item)
  25. }
  26. return list
  27. }
  28. }
  29. else {
  30. list = ArrayList<T>()
  31. }
  32. var count = 0
  33. for (item in this) {
  34. if (count++ >= n) list.add(item)
  35. }
  36. return list.optimizeReadOnlyList()
  37. }

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.drop(5)
  3. [11, 12, 16]
  4. >>> list.drop(100)
  5. []
  6. >>> list.drop(0)
  7. [2, 4, 6, 8, 9, 11, 12, 16]
  8. >>> list.drop(-1)
  9. java.lang.IllegalArgumentException: Requested element count -1 is less than zero.
  10. at kotlin.collections.CollectionsKt___CollectionsKt.drop(_Collections.kt:538)
  11. ```#### `dropWhile(predicate: (T) -> Boolean)` 去除满足条件的元素返回剩下的元素的子集合
  12. 函数定义:
  13. ```kotlin
  14. public inline fun <T> Iterable<T>.dropWhile(predicate: (T) -> Boolean): List<T> {
  15. var yielding = false
  16. val list = ArrayList<T>()
  17. for (item in this)
  18. if (yielding)
  19. list.add(item)
  20. else if (!predicate(item)) {
  21. list.add(item)
  22. yielding = true
  23. }
  24. return list
  25. }

去除满足条件的元素,当遇到一个不满足条件的元素时,中止操作,返回剩下的元素子集合。

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.dropWhile({it%2==0})
  3. [9, 11, 12, 16]
  4. ```#### `dropLast(n: Int)` 从最后去除n个元素
  5. 函数定义:
  6. ```kotlin
  7. public fun <T> List<T>.dropLast(n: Int): List<T> {
  8. require(n >= 0) { "Requested element count $n is less than zero." }
  9. return take((size - n).coerceAtLeast(0))
  10. }

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.dropLast(3)
  3. [2, 4, 6, 8, 9]
  4. >>> list.dropLast(100)
  5. []
  6. >>> list.dropLast(0)
  7. [2, 4, 6, 8, 9, 11, 12, 16]
  8. >>> list.dropLast(-1)
  9. java.lang.IllegalArgumentException: Requested element count -1 is less than zero.
  10. at kotlin.collections.CollectionsKt___CollectionsKt.dropLast(_Collections.kt:573)
  11. ```#### `dropLastWhile(predicate: (T) -> Boolean)` 从最后满足条件的元素
  12. 函数定义:
  13. ```kotlin
  14. public inline fun <T> List<T>.dropLastWhile(predicate: (T) -> Boolean): List<T> {
  15. if (!isEmpty()) {
  16. val iterator = listIterator(size)
  17. while (iterator.hasPrevious()) {
  18. if (!predicate(iterator.previous())) {
  19. return take(iterator.nextIndex() + 1)
  20. }
  21. }
  22. }
  23. return emptyList()
  24. }

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.dropLastWhile({it%2==0})
  3. [2, 4, 6, 8, 9, 11]
  4. ```#### `slice(indices: IntRange)` 取开始下标至结束下标元素子集合
  5. 函数定义:
  6. ```kotlin
  7. public fun <T> List<T>.slice(indices: IntRange): List<T> {
  8. if (indices.isEmpty()) return listOf()
  9. return this.subList(indices.start, indices.endInclusive + 1).toList()
  10. }

代码示例:

  1. val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list
  3. [2, 4, 6, 8, 9, 11, 12, 16]
  4. >>> list.slice(1..3)
  5. [4, 6, 8]
  6. >>> list.slice(2..7)
  7. [6, 8, 9, 11, 12, 16]
  8. >>> list
  9. [2, 4, 6, 8, 9, 11, 12, 16]
  10. >>> list.slice(1..3)
  11. [4, 6, 8]
  12. >>> list.slice(2..7)
  13. [6, 8, 9, 11, 12, 16]
  14. ```#### `slice(indices: Iterable<Int>) `返回指定下标的元素子集合
  15. 函数定义:
  16. ```kotlin
  17. public fun <T> List<T>.slice(indices: Iterable<Int>): List<T> {
  18. val size = indices.collectionSizeOrDefault(10)
  19. if (size == 0) return emptyList()
  20. val list = ArrayList<T>(size)
  21. for (index in indices) {
  22. list.add(get(index))
  23. }
  24. return list
  25. }

这个函数从签名上看,不是那么简单直接。从函数的定义看,这里的indices是当做原来集合的下标来使用的。

代码示例:

  1. >>> list
  2. [2, 4, 6, 8, 9, 11, 12, 16]
  3. >>> list.slice(listOf(2,4,6))
  4. [6, 9, 12]

我们可以看出,这里是取出下标为2,4,6的元素。而不是直观理解上的,去掉元素2,4,6。#### filterTo(destination: C, predicate: (T) -> Boolean) 过滤出满足条件的元素并赋值给destination

函数定义:

  1. public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
  2. for (element in this) if (predicate(element)) destination.add(element)
  3. return destination
  4. }

把满足过滤条件的元素组成的子集合赋值给入参destination。

代码示例:

  1. >>> val list = listOf(1,2,3,4,5,6,7)
  2. >>> val dest = mutableListOf<Int>()
  3. >>> list.filterTo(dest,{it>3})
  4. [4, 5, 6, 7]
  5. >>> dest
  6. [4, 5, 6, 7]
  7. ```#### `filter(predicate: (T) -> Boolean)`过滤出满足条件的元素组成的子集合
  8. 函数定义:
  9. ```kotlin
  10. public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
  11. return filterTo(ArrayList<T>(), predicate)
  12. }

相对于filterTo函数,filter函数更加简单易用。从源码我们可以看出,filter函数直接调用的filterTo(ArrayList<T>(), predicate), 其中入参destination被直接默认赋值为ArrayList<T>()

代码示例:

  1. >>> val list = listOf(1,2,3,4,5,6,7)
  2. >>> list.filter({it>3})
  3. [4, 5, 6, 7]

另外,还有下面常用的过滤函数:

filterNot(predicate: (T) -> Boolean), 用来过滤所有不满足条件的元素 ; filterNotNull() 过滤掉null元素。