用函数式编程来解决复杂计算问题的编程范式称为函数式编程. 每个函数都针对集合设计,它将输入集合经过变换,过滤,合并等多个简单函数组合后变成目标集合.
- 函数式编程的设计理念就是不可变数据的副本在链上的函数间传递的过程
- 处理函数处理的都是单个数据元素,变换后自动合并为新的集合
函数式编程三个大类
- 变换transform
- 过滤 filter
- 合并 combine
变换 map / flatmap
针对集合元素的操作
map
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C {
for (item in this)
destination.add(transform(item))
return destination
}
val listOf = listOf("monkey", "giraffe" , "zebra")
listOf.map {it.length }.run { println(this) } // [6, 7, 5]
flatmap
将集合元素平铺.它将输入集合中的每个元素做变换后,添加到同一集合中
public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {
return flatMapTo(ArrayList<R>(), transform)
}
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapTo(destination: C, transform: (T) -> Iterable<R>): C {
for (element in this) {
val list = transform(element)
destination.addAll(list)
}
return destination
}
val listOf = listOf("monkey", "giraffe" , "zebra")
listOf.flatMap { it.toSet()}.run { println(this) } //[m, o, n, k, e, y, g, i, r, a, f, e, z, e, b, r, a]
过滤 filter
过滤函数根据predicate的返回值来确定是否将遍历元素加入到结果集合中,如果为true则添加,为false则丢弃.
val listOf = listOf("monkey", "giraffe" , "zebra" )
listOf.filter { it.contains("a") }.run { println(this) } //[giraffe, zebra]
//例子,求素数
val intList = listOf(10, 8, 5, 7, 3, 100, 107, 233)
intList.filter { number->
(2 until number).map { number % it }.none { it == 0 }
}
合并
zip
将两个集合转化为健值对的map , 注意长度是按照最短集合来定的
.比如elephant就丢弃了
val l = listOf("monkey", "giraffe" , "zebra", "elephant")
var weight = listOf(100 ,200 , 300)
l.zip(weight).run { println(this) } // [(monkey, 100), (giraffe, 200), (zebra, 300)]
fold
累加器,初始值 + 处理函数(每个元素) 的结果
//累加的列子
var weight = listOf(100 ,200 , 300)
weight.fold(10){acc,it->
acc + it * 3
}.run { println(this) } // 1810 , acc是累加器的结果
// 求素数的进阶版例子
fun Int.isPrime() = ! (2 until this).map { this % it == 0 }.fold(false){acc, b -> acc || b }
listOf( 1 , 3 , 10 , 7 , 11 , 21).filter { it.isPrime() }.run { println(this) }
//求 5000以内的素数
(2..5000).filter { it.isPrime() }.take(1000).run { println(this) }
序列
产生未知数量的序列,不记录数据,也不记录未知,所有的数据都可以加入到序列中.
generateSequence
根据种子seed和函数,生产下一个数据.数据源本身是无限的.
//寻找1000个素数
generateSequence(1 ){ it + 2 }.filter { it.isPrime() }.take(1000).run { println(this) }