kotlin 内部迭代和延迟计算

一、内部的迭代函数

filter(e -> 返回true和false) 判断数值是否加入新的数组
map(e -> 返回调整e之后的值) 对数组中每个数进行调整,并存入新的数组
reduce(total, e -> 返回新的total) total是统计结果,e是当前遍历到参数;返回新的total作为数组下一个参数total
joinToString(", ") 将数组的每个值通过逗号连接起来
sum() 将数组的每个值相加
first() 返回数组的第一个值
last() 返回数组的最后一个值
flatten() 可以将二维的list转化为1维,如果三维转换为1维则需要两次调用该函数
flatMap{e -> listOf()} 是map和flatten的组合
sortedBy{e -> xxx} 对指定的参数进行从小到大排序
sortedByDescending{e -> xxx} 从大到小排序 

val numbers = listOf(10, 12, 15, 17, 18, 19)
numbers.filter{e -> e % 2 == 0}
.forEach{e -> print("$e, ")}

如上过滤出numbers中的偶数,然后通过forEach遍历所有的元素

val doubledEven = numbers.filter{it % 2 == 0}.map{it * 2}
// 过滤出偶数,并且每个偶数乘以2

 

2、none/any/all

none: 没有一个元素符合条件 则会返回true

any: 至少有一个元素符合条件 则会返回true

all: 所有元素都符合条件 则会返回true

val numbers = listOf(10, 12, 15, 17, 18, 19, 21)

println(numbers.none()) // false 因为numbers中有元素,所以返回false
println(numbers.any())  // true 因为numbers中至少有一个元素,所以返回true
println(numbers.none{it % 7 == 0}) // false  21能够被7整除,所以返回false
println(numbers.any{it % 7 == 0}) // true    21能够被7整除,所以返回true
println(numbers.all{it % 2 == 0}) // false   numbers列表中有奇数,所以返回false
println(listOf(2,4,6).all{it % 2 == 0}) // true    列表中的所有数值都能够被2整除,所有返回true

 

二、延迟计算

sequence 使用sequence进行内部的计算,很多时候可以优化部分的性能

复制代码
fun isAdult(person: Person): Boolean {
    println("isAdult called for ${person.firstName}")
    return person.age > 17
}

fun fetchFirstName(person: Person): String {
    println("fetchFirstName called for ${person.firstName}")
    return person.firstName
}

val nameOfFirstAdult = people.asSequence().filter(::isAdult).map(::fetchFirstName).first()
println(nameOfFirstAdult)

/*
如下是上述返回的结果
isAdult called for aaa2
isAdult called for aaa3
fetchFirstName called for aaa3
aaa3
*/
复制代码

那么如果不使用sequence,则结果为

复制代码
val nameOfFirstAdult = people.filter(::isAdult).map(::fetchFirstName).first()
println(nameOfFirstAdult)

/*
如下是上述返回的结果
isAdult called for aaa2
isAdult called for aaa3
isAdult called for aaa4
isAdult called for aaa5
isAdult called for aaa6
isAdult called for aaa7
fetchFirstName called for aaa3
fetchFirstName called for aaa4
fetchFirstName called for aaa6
fetchFirstName called for aaa7
aaa3
*/
复制代码

则可以看到使用sequence,会进行lazy的计算

 

2、generateSequence

当要使用无限的循环,则可以使用generateSequence, 懒操作如下是使用generateSequence和正常的sequence

复制代码
fun isPrime(n: Long) = n > 1 && (2 until n).none{i -> n % i == 0L}
fun nextPrime(n: Long): Long = 
if (isPrime(n + 1)) n + 1 else nextPrime(n + 1)

val primes = generateSequence(5, ::nextPrime)
println(primes.take(6).toList())

val primes1 = sequence {
    var i: Long = 0
    while (true) {
        i++
        if (isPrime(i)) {
            yield(i)
        }
    }
}

println(primes1.drop(2).take(6).toList())
复制代码

如上返回的结果均为:[5, 7, 11, 13, 17, 19]

generateSequence的第一个参数是开始的数值,第二个是对应的调用函数

如果把nextPrime函数换成如下

复制代码
fun nextPrime(n: Long): Long {
    println("nextPrime:" + n)
    var ret: Long
    if (isPrime(n + 1)) {
        ret = n + 1
    } else {
        ret = nextPrime(n + 1)
    }
    return ret
}
复制代码

然后使用generateSequence进行调用返回的结果如下

复制代码
val primes = generateSequence(5, ::nextPrime)
println(primes.take(6).toList())

/*
注意看下该函数;当返回给generateSequence之后,下一次generateSequence会以当前返回的值作为下一次的输入
nextPrime:5
nextPrime:6
nextPrime:7
nextPrime:8
nextPrime:9
nextPrime:10
nextPrime:11
nextPrime:12
nextPrime:13
nextPrime:14
nextPrime:15
nextPrime:16
nextPrime:17
nextPrime:18
*/
复制代码

 

posted @   LCAC  阅读(104)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示