代码之家  ›  专栏  ›  技术社区  ›  aschoerk

kotlin的流处理

  •  2
  • aschoerk  · 技术社区  · 7 年前
    • Kotlin将如何使用以下代码?
    • 是否将5000000个整数的集合创建为临时集合,或者筛选器是否将其结果立即反馈给 forEach 也就是说,只会查看20个整数?
    • 如果没有,我将如何避免中间收集?

    代码:

    class Tests {
        @Test
        fun test() {
            var counter = 0
            (1..10_000_000).filter { it % 2 == 1 }.forEach {
                counter++
                if (counter > 10)
                    return
            }
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  5
  •   hotkey    7 年前

    您的代码示例在上使用操作 Iterable<T> ,这一点非常有效: .filter { ... } 调用将处理整个范围并生成一个存储中间结果的列表。

    要改变这一点,请考虑使用 Sequence<T> (例如 .asSequence() )这是懒惰的,所以 中间的 操作,如 .filter { ... } 生成另一个惰性序列,并仅在查询项时执行该工作 航空站 操作,如 .forEach { ... } :

    (1..10000000).asSequence()
        .filter { it % 2 == 1 } 
        .forEach { /* ... */ }
    

    请参见: Kotlin's Iterable and Sequence look exactly same. Why are two types required?

        2
  •  1
  •   s1m0nw1    7 年前

    实际上,只需添加 println(it) 进入 filter :

    //...
    .filter {
       println(it)
       it % 2 == 1
    }
    //...
    

    你会看到的 每一个 打印的编号。那是因为你的处理过程如所解释的那样热切地工作 here .

    如前所述,懒惰 Sequences 救援: (1..10_000_000).asSequence()

    现在 println(it) 在里面 滤器 将只打印数字 1..21 ,这在您的示例中绝对是可取的。