【Kotlin】函数式编程 ③ ( 早集合与惰性集合 | 惰性集合-序列 | generateSequence 序列创建函数 | 序列代码示例 | take 扩展函数分析 )

这篇具有很好参考价值的文章主要介绍了【Kotlin】函数式编程 ③ ( 早集合与惰性集合 | 惰性集合-序列 | generateSequence 序列创建函数 | 序列代码示例 | take 扩展函数分析 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。





一、及早集合与惰性集合



及早集合 与 惰性集合 :

  • 及早集合 : Eager Collection , 指的是 List , Map , Set 等集合 , 这些集合创建后 , 需要 将元素提前存储到集合中 , 然后才能访问 ;
  • 惰性集合 : Lazy Collection , 在 集合刚创建时不必将集合元素放进去 , 当使用这些元素时才生成 , 这些 集合元素按需产生 ;

在 惰性集合 中 集合元素的 初始化 是 惰性初始化 ;





二、惰性集合-序列



Kotlin 中提供了一个 惰性集合 , 称为 序列 Sequence ;

在 序列 中 , 不记录元素个数 , 也 不对其内容进行排序 , 在该 <font color=bluegreen序列中 元素可能有无限多个 ;

序列中的元素 是由 数据源 产生的 , 其元素个数 可能有无限多个 ;





三、generateSequence 序列创建函数




1、函数简介


“generateSequence” 函数 是 Kotlin 标准库 中的一个函数,属于 Kotlin 的 序列生成器

“generateSequence” 函数 可以生成一个 惰性序列,并且支持从指定的序列中生成元素。

生成的序列是惰性的,意味着 请求元素时,才会 生成相应的元素。这使得开发者可以在 不需要处理整个序列的情况下,处理序列中的元素。


2、函数原型


Kotlin 提供的 " generateSequence " 标准库函数 , 原型如下 :

/**
 * 返回由起始值[seed]和函数[nextFunction]定义的序列,每次迭代时,该函数被调用以根据前一个值计算下一个值
 *
 * 序列产生值,直到遇到第一个null值。
 * 如果[seed]是null,则生成一个空序列。
 * 
 * 该序列可以多次迭代,每次都从[seed]开始。
 *
 * @see kotlin.sequences.sequence
 *
 * @sample samples.collections.Sequences.Building.generateSequenceWithSeed
 */
@kotlin.internal.LowPriorityInOverloadResolution
public fun <T : Any> generateSequence(seed: T?, nextFunction: (T) -> T?): Sequence<T> =
    if (seed == null)
        EmptySequence
    else
        GeneratorSequence({ seed }, nextFunction)
  • seed: T? 参数 : 该参数是 序列的第一个元素值 , 初始值 , 又称为随机种子 ;
  • nextFunction: (T) -> T? 参数 : 该参数是一个 匿名函数 / Lambda 表达式 / 闭包 , 可以 根据前一个值计算出下一个值 ;

3、函数简介


Kotlin 的 generateSequence 函数是一种 生成序列 的方法,它可以生成 可迭代的、有限或无限的序列


generateSequence 函数 接收两个参数:

  • 起始值 seed
  • 生成下一个值的 匿名函数 nextFunction。

每次迭代时,nextFunction 都会被调用以生成下一个值,并且该序列会不断生成值,直到遇到第一个 null 值。如果起始值为 null,那么将会生成一个空序列。

该序列可以 多次迭代,每次都从起始值开始。这是因为 generateSequence 返回一个实现了 Sequence 接口的对象,这意味着你可以 在多次迭代之间重用该序列。

通过使用 generateSequence,你可以简化代码,提高可读性和可维护性,并且可以 生成更复杂的序列,如斐波那契数列、自然数序列等。


4、使用示例


使用方法 : 使用 “generateSequence” 函数 并 传递一个函数作为参数 ; 函数必须返回 “Nullable” 类型的值,当序列不再生成元素时返回 “null”。

“generateSequence” 函数 是一种高效且灵活的 生成序列 的方法,它可以用于许多应用程序,如 生成指定数量的元素、生成无限循环的序列等。


示例 : 以下代码生成一个从 1 开始的整数序列:

val sequence = generateSequence(1) { it + 1 }
println(sequence.take(10).toList()) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]




四、序列代码示例



取 从 2 开始的 前 20 个 素数 ;


1、使用传统的函数式编程实现


代码示例 : 下面的代码中 , 从 1 ~ 1000 的区间内查找素数 , 必须将 1000 个元素的集合生成出来 , 然后逐个遍历 ;

/**
 * 为 Int 定义扩展函数, 判断接收者是否是素数
 */
fun Int.isPrimeNumber(): Boolean {
    // number 参数是被遍历的 接收者集合 的 受检元素
    // 符合下面的要求 才会被放入新集合
    // 遍历时每个 受检元素 都要 被 [2..number - 1] 区间的数值进行遍历
    val isPrimeNumber = (2..this - 1)
        // 计算 number 与 [2..number - 1] 区间中的数值 相除的 余数
        // 也就是验证 是否 只有 1 和 其本身 可以被其整除
        .map { this % it }
        // 通过 map 变换计算出的余数
        // 不能出现 余数 为 0 的情况
        // 一旦出现 就返回 false
        .none{it == 0}
    return isPrimeNumber
}

fun main() {
    val numbers = (2..1000)
        .toList()   // 将 IntRange 转为 List 集合
        .filter { it.isPrimeNumber() }  // 筛选出集合中是素数的人
        .take(20) // 从筛选出来的数值中取 20 个元素

    println(numbers)
}

执行结果 :

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]

kotlin generatesequence,Kotlin,kotlin,惰性集合,序列,Sequence,及早集合


2、使用序列 Sequence 实现


使用传统方式实现素数查找 , 如 : 从 1 ~ 1000 的区间内查找素数 , 必须将 1000 个元素的集合生成出来 , 然后逐个遍历 ;

如果使用 序列 Sequence 实现 , 则 只需要实现需要的部分 , 没有遍历的元素不会生成 ;


代码示例 :

/**
 * 为 Int 定义扩展函数, 判断接收者是否是素数
 */
fun Int.isPrimeNumber(): Boolean {
    // number 参数是被遍历的 接收者集合 的 受检元素
    // 符合下面的要求 才会被放入新集合
    // 遍历时每个 受检元素 都要 被 [2..number - 1] 区间的数值进行遍历
    val isPrimeNumber = (2..this - 1)
        // 计算 number 与 [2..number - 1] 区间中的数值 相除的 余数
        // 也就是验证 是否 只有 1 和 其本身 可以被其整除
        .map { this % it }
        // 通过 map 变换计算出的余数
        // 不能出现 余数 为 0 的情况
        // 一旦出现 就返回 false
        .none{it == 0}
    return isPrimeNumber
}

fun main() {
    val numbers = generateSequence(2) { it + 1 }    // 设置初始值为 2 , 然后每次值自增 1
        .filter { it.isPrimeNumber() }  // 遍历序列元素 , 查询是否是素数
        .take(20)   // 取前 20 个素数

    println(numbers)
}

执行结果 :

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]

kotlin generatesequence,Kotlin,kotlin,惰性集合,序列,Sequence,及早集合


3、take 扩展函数分析


下面是 普通集合 调用的 take 扩展函数 原型序列 Sequence 调用的 take 扩展函数 的对比 , 两个 函数 是不同的 , take 函数决定了 取值的个数 ;

序列 Sequence 调用 take 函数时 , take 函数调用了序列的部分内容 , 决定了 序列 Sequence 的执行次数 , 生成多少元素 , 如 : 上述代码示例中 take 函数取够了 20 个素数 , 之后 Sequence 就不再继续生成后续元素了 ;


普通集合 调用的 take 扩展函数 原型 和 序列 Sequence 调用的 take 扩展函数 的对比 :文章来源地址https://www.toymoban.com/news/detail-784245.html

  • 普通集合 调用的 take 扩展函数 原型 :
/**
 * Returns a list containing first [n] elements.
 * 
 * @throws IllegalArgumentException if [n] is negative.
 * 
 * @sample samples.collections.Collections.Transformations.take
 */
public fun <T> Iterable<T>.take(n: Int): List<T> {
    require(n >= 0) { "Requested element count $n is less than zero." }
    if (n == 0) return emptyList()
    if (this is Collection<T>) {
        if (n >= size) return toList()
        if (n == 1) return listOf(first())
    }
    var count = 0
    val list = ArrayList<T>(n)
    for (item in this) {
        list.add(item)
        if (++count == n)
            break
    }
    return list.optimizeReadOnlyList()
}
  • 序列 Sequence 调用的 take 扩展函数 原型 :
/**
 * Returns a sequence containing first [n] elements.
 *
 * The operation is _intermediate_ and _stateless_.
 * 
 * @throws IllegalArgumentException if [n] is negative.
 * 
 * @sample samples.collections.Collections.Transformations.take
 */
public fun <T> Sequence<T>.take(n: Int): Sequence<T> {
    require(n >= 0) { "Requested element count $n is less than zero." }
    return when {
        n == 0 -> emptySequence()
        this is DropTakeSequence -> this.take(n)
        else -> TakeSequence(this, n)
    }
}

到了这里,关于【Kotlin】函数式编程 ③ ( 早集合与惰性集合 | 惰性集合-序列 | generateSequence 序列创建函数 | 序列代码示例 | take 扩展函数分析 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 离散数学及应用 -- 02 基本结构:集合、函数、序列、求和与矩阵

    目录 集合 集合运算 函数(映射、变换) 序列 求和 ​编辑集合的基数 矩阵 集合是对象的一个无序的聚集,对象也称为集合的元素或成员。集合包含它的元素。         ∈A:a是集合A中一个元素         ∉A:a是集合A中一个元素 描述集合的方式:         花名册方

    2024年02月01日
    浏览(48)
  • 【Kotlin】函数式编程 ② ( 过滤函数 | predicate 谓词函数 | filter 过滤函数 | 合并函数 | zip 函数 | folder 函数 | 函数式编程意义 )

    函数式编程的三种函数类别 : 变换 Transform 过滤 Filter 合并 Combine 在上一篇博客 函数式编程 ① 中 讲解了 变换函数 map 函数 与 flatMap 函数 , 本篇博客中着重讲解 过滤函数 和 合并函数 ; 过滤函数 是 函数式编程 中的函数类型 , 一般该类型函数 接收一个 Predicate 谓词函数 作为参

    2024年02月03日
    浏览(66)
  • 【Kotlin】函数式编程 ① ( 函数式编程简介 | 高阶函数 | 函数类别 | Transform 变换函数 | 过滤函数 | 合并函数 | map 变换函数 | flatMap 变换函数 )

    编程范式 指的是 使用某种编程语言的 编程套路 或 编程习惯 ; 使用 Java 等高级语言进行的编程 , 编程范式 一般都是 面向对象编程 ; 与 面向对象编程 同等级的另外一种 编程范式 是 函数式编程 , 函数式编程 不依赖于 指定的语言 , 所有的编程语言都可以使用 函数式编程范式

    2024年01月18日
    浏览(47)
  • JUC并发编程-集合不安全情况以及Callable线程创建方式

    1)List 不安全 ArrayList 在并发情况下是不安全的 解决方案 : 1.Vector 2.Collections.synchonizedList() 3. CopyOnWriteArrayList 核心思想 是,如果有 多个调用者(Callers)同时要求相同的资源 (如内存或者是磁盘上的数据存储),他们 会共同获取相同的指针指向相同的资源 , 直到某个调用者

    2024年01月23日
    浏览(48)
  • Scala编程基础:表达式、函数、模式匹配与集合操作

    本文详细介绍了Scala编程的基础知识,包括表达式的使用,方法与函数的区别,模式匹配的各种模式,以及Scala Trait(特质)的定义和使用。

    2024年04月14日
    浏览(51)
  • Kotlin基本语法3集合

           

    2024年02月20日
    浏览(47)
  • Kotlin中的集合操作

    Kotlin 在集合操作上提供了一系列的扩展函数,使其变得非常强大且易于使用。以下是一些在Kotlin中常用的集合操作API,以及如何使用它们的示例: 1. Filtering (过滤) ​ 使用 filter 函数来过滤集合中符合条件的元素。 2. Transforming (转换) ​ 使用 map 函数能够将集合中的元素进行

    2024年01月18日
    浏览(45)
  • 学习Kotlin~集合

    List集合 只读和可变 可变运算 集合遍历 解构 Set集合 Array数组 Map集合

    2024年02月11日
    浏览(41)
  • kotlin 过滤集合中的特定的元素

    kotlin提供了过滤集合很方便过滤集合中特定的元素 1 如果是同一种类型的操作,建议使用filter 或者是partition 例如过滤出字符长度大于3的元素 使用partition 使用filter 如果集合中是不同的类型过滤出相同的类型建议使用filterIsInstance

    2024年02月03日
    浏览(39)
  • kotlin获取泛型集合的类型信息

    通过  reified 和内联函数来实现 注:将reified 和 inline去掉就无法通过T::class.java获取到类型,因为编译的时候会进行类型擦除,所以在运行的时候已经无法获取到类型了,这是Java兼容性的处理机制,kotlin通过reified和inline优化了泛型,实现了运行时获取类型 。 Java 5才引

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包