【问题标题】:How does sorting work in lazy sequences?排序如何在惰性序列中工作?
【发布时间】:2018-02-18 14:57:02
【问题描述】:

假设我正在使用惰性序列和某种无限序列,那么我尝试编写类似(伪代码)的内容:

Sequence([1,2,3,...])
   .sortDescending()
   .take(10);

在这种情况下,我先排序,然后采用 10 元素。排序函数如何在无限序列上执行?

一个例子是 Kotlin 序列:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/sorted.html

【问题讨论】:

    标签: lazy-evaluation lazy-sequences


    【解决方案1】:

    sortDescending 方法将对应的序列转换为MutableList,该MutableList 正在排序,然后转换回新序列。下面展示了内部使用的sortedWith函数:

    /**
     * Returns a sequence that yields elements of this sequence sorted according to the specified [comparator].
     * The operation is _intermediate_ and _stateful_.
     */
    public fun <T> Sequence<T>.sortedWith(comparator: Comparator<in T>): Sequence<T> {
        return object : Sequence<T> {
            override fun iterator(): Iterator<T> {
                val sortedList = this@sortedWith.toMutableList()
                sortedList.sortWith(comparator)
                return sortedList.iterator()
            }
        }
    }
    

    所以当你有一个无限序列时,比如:

    generateSequence(1) {
        it * 2
    }
    

    并且您在该序列上调用所描述的函数(以及像forEach { println(it) } 这样的 terminate 函数),所有元素都会在某个时候添加到列表中,这肯定会失败,因为进入无限循环:

    java.lang.OutOfMemoryError: Java heap space
    

    您可能希望对固定数量的元素进行排序,如下所示:

    generateSequence(1) {
        it * 2
    }.take(10)
     .sortedDescending()
     .forEach { println(it) }
    

    【讨论】:

      猜你喜欢
      • 2015-03-09
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 2011-03-15
      • 2019-09-16
      • 2014-11-10
      • 2016-09-19
      • 2019-04-19
      相关资源
      最近更新 更多