过滤操作函数

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. []

takeWhile(predicate: (T) -> Boolean): List<T> 挑出满足条件的元素的子集合

函数定义:

  1. public inline fun <T> Iterable<T>.takeWhile(predicate: (T) -> Boolean): List<T> {
  2. val list = ArrayList<T>()
  3. for (item in this) {
  4. if (!predicate(item))
  5. break
  6. list.add(item)
  7. }
  8. return list
  9. }

从第一个元素开始,判断是否满足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]

takeLast 挑出后n个元素的子集合

函数定义:

  1. public fun <T> List<T>.takeLast(n: Int): List<T> {
  2. require(n >= 0) { "Requested element count $n is less than zero." }
  3. if (n == 0) return emptyList()
  4. val size = size
  5. if (n >= size) return toList()
  6. if (n == 1) return listOf(last())
  7. val list = ArrayList<T>(n)
  8. if (this is RandomAccess) {
  9. for (index in size - n .. size - 1)
  10. list.add(this[index])
  11. } else {
  12. for (item in listIterator(n))
  13. list.add(item)
  14. }
  15. return list
  16. }

从集合倒数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)

takeLastWhile(predicate: (T) -> Boolean) 从最后开始挑出满足条件元素的子集合

函数定义:

  1. public inline fun <T> List<T>.takeLastWhile(predicate: (T) -> Boolean): List<T> {
  2. if (isEmpty())
  3. return emptyList()
  4. val iterator = listIterator(size)
  5. while (iterator.hasPrevious()) {
  6. if (!predicate(iterator.previous())) {
  7. iterator.next()
  8. val expectedSize = size - iterator.nextIndex()
  9. if (expectedSize == 0) return emptyList()
  10. return ArrayList<T>(expectedSize).apply {
  11. while (iterator.hasNext())
  12. add(iterator.next())
  13. }
  14. }
  15. }
  16. return toList()
  17. }

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

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.takeLastWhile({it%2==0})
  3. [12, 16]

drop(n: Int) 去除前n个元素返回剩下的元素的子集合

函数定义:

  1. public fun <T> Iterable<T>.drop(n: Int): List<T> {
  2. require(n >= 0) { "Requested element count $n is less than zero." }
  3. if (n == 0) return toList()
  4. val list: ArrayList<T>
  5. if (this is Collection<*>) {
  6. val resultSize = size - n
  7. if (resultSize <= 0)
  8. return emptyList()
  9. if (resultSize == 1)
  10. return listOf(last())
  11. list = ArrayList<T>(resultSize)
  12. if (this is List<T>) {
  13. if (this is RandomAccess) {
  14. for (index in n..size - 1)
  15. list.add(this[index])
  16. } else {
  17. for (item in listIterator(n))
  18. list.add(item)
  19. }
  20. return list
  21. }
  22. }
  23. else {
  24. list = ArrayList<T>()
  25. }
  26. var count = 0
  27. for (item in this) {
  28. if (count++ >= n) list.add(item)
  29. }
  30. return list.optimizeReadOnlyList()
  31. }

代码示例:

  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)

dropWhile(predicate: (T) -> Boolean) 去除满足条件的元素返回剩下的元素的子集合

函数定义:

  1. public inline fun <T> Iterable<T>.dropWhile(predicate: (T) -> Boolean): List<T> {
  2. var yielding = false
  3. val list = ArrayList<T>()
  4. for (item in this)
  5. if (yielding)
  6. list.add(item)
  7. else if (!predicate(item)) {
  8. list.add(item)
  9. yielding = true
  10. }
  11. return list
  12. }

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

代码示例:

  1. >>> val list = listOf(2,4,6,8,9,11,12,16)
  2. >>> list.dropWhile({it%2==0})
  3. [9, 11, 12, 16]

dropLast(n: Int) 从最后去除n个元素

函数定义:

  1. public fun <T> List<T>.dropLast(n: Int): List<T> {
  2. require(n >= 0) { "Requested element count $n is less than zero." }
  3. return take((size - n).coerceAtLeast(0))
  4. }

代码示例:

  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)

dropLastWhile(predicate: (T) -> Boolean) 从最后满足条件的元素

函数定义:

  1. public inline fun <T> List<T>.dropLastWhile(predicate: (T) -> Boolean): List<T> {
  2. if (!isEmpty()) {
  3. val iterator = listIterator(size)
  4. while (iterator.hasPrevious()) {
  5. if (!predicate(iterator.previous())) {
  6. return take(iterator.nextIndex() + 1)
  7. }
  8. }
  9. }
  10. return emptyList()
  11. }

代码示例:

  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]

slice(indices: IntRange) 取开始下标至结束下标元素子集合

函数定义:

  1. public fun <T> List<T>.slice(indices: IntRange): List<T> {
  2. if (indices.isEmpty()) return listOf()
  3. return this.subList(indices.start, indices.endInclusive + 1).toList()
  4. }

代码示例:

  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]

slice(indices: Iterable<Int>)返回指定下标的元素子集合

函数定义:

  1. public fun <T> List<T>.slice(indices: Iterable<Int>): List<T> {
  2. val size = indices.collectionSizeOrDefault(10)
  3. if (size == 0) return emptyList()
  4. val list = ArrayList<T>(size)
  5. for (index in indices) {
  6. list.add(get(index))
  7. }
  8. return list
  9. }

这个函数从签名上看,不是那么简单直接。从函数的定义看,这里的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]

filter(predicate: (T) -> Boolean)过滤出满足条件的元素组成的子集合

函数定义:

  1. public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
  2. return filterTo(ArrayList<T>(), predicate)
  3. }

相对于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元素。