我正在使用函式式編程風格來解決 Leetcode 的簡單問題,Count the Number of Consistent Strings。這個問題的前提很簡單:計算“所有值都在另一個集合中”的謂詞所持有的值的數量。
我能夠非常簡潔地做到這一點:
class Solution {
fun countConsistentStrings(allowed: String, words: Array<String>): Int {
val permitted = allowed.toSet()
return words.count{it.all{it in permitted}}
}
}
我知道 Java 流是懶惰的,但讀過 Kotlin 只是在asSequence使用時才懶惰,否則就會急切。
對于基于使用any,none或的謂詞的布林值的縮減,all對我來說最有意義的是這應該懶惰地完成(例如,單個falseinall應該評估整個運算式false并停止評估其他元素的謂詞)。
這些操作是以這種方式實作的,還是它們仍然像 Kotlin 中的其他操作一樣急切地完成。如果是這樣,有沒有辦法懶惰地做它們?
uj5u.com熱心網友回復:
我認為你過度解釋了懶惰和熱切的意思。就像“eagerly”一樣,意味著總是以盡可能低效的方式做所有事情。
惰性集合(Streams API、序列)嘗試推遲計算其內容,直到必要時。另一方面,常規集合在請求時立即執行操作。但這并不意味著如果我們向常規集合詢問它的第一個元素,它會無緣無故地遍歷所有這些元素。
事實上,對于可迭代物件和序列,這些函式的實作方式幾乎完全相同。不同之處在于其他轉換和運算子。下面是一個例子any():
public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {
if (this is Collection && isEmpty()) return false
for (element in this) if (predicate(element)) return true
return false
}
public inline fun <T> Sequence<T>.any(predicate: (T) -> Boolean): Boolean {
for (element in this) if (predicate(element)) return true
return false
}
uj5u.com熱心網友回復:
不,這些方法并不懶惰。
首先,請記住,每個名稱都有多個方法:兩個定義 on Sequence,兩個定義在 13 種陣列型別中的每Map一個上,兩個 on ,一個 on Iterable。很明顯,您只對定義在 上的那些感興趣Sequence,因為其他型別不支持惰性。
所以,讓我們看看檔案!、for和for方法的檔案Sequence.any()都說:Sequence.none()Sequence.all()
操作是終端。
為了確認這意味著什么,package的檔案kotlin.sequences說:
如果序列操作回傳另一個序列,該序列是延遲生成的,則稱為中間,否則操作為終端。
所以這些方法并不懶惰;執行時,它們會根據需要對序列進行評估以產生所需的值。(但是,他們不會對它進行超出需要的進一步評估,這可能是您要問的。畢竟,這就是使用序列的意義所在!)
(事實上??,你可以從它們的型別中看出,它們不可能是惰性的:它們每個都回傳一個Boolean值,該值要么是真要么是假。為了支持惰性求值,它們需要回傳一個Future或類似的物件,其可以呼叫 getter 以產生最終結果。但 aBoolean已經是最終結果。)
uj5u.com熱心網友回復:
檔案沒有明確說明,但這很容易測驗。
class A : Iterable<String>, Iterator<String> {
public override fun iterator(): Iterator<String> {
return this
}
public override fun hasNext(): Boolean {
return true
}
public override fun next(): String {
return "test"
}
}
fun main(args: Array<String>) {
val a = A()
println(a.any { x -> x == "test" })
println(a.none { x -> x == "test" })
println(a.all { x -> x != "test" })
}
在這里,A是一個愚蠢的可迭代類,它"test"永遠產生并且永遠不會用完。然后我們使用any, none, andall來檢查它是否產生"test"。這是一個無限可迭代的,所以如果這三個函式中的任何一個想要嘗試耗盡它,程式就會永遠掛起。但是你可以自己運行它,你會看到 atrue和 two false。程式終止。因此,這三個函式中的每一個在分別找到匹配、不匹配和不匹配時都會停止。
在線嘗試!
uj5u.com熱心網友回復:
簡而言之,Kotlin 中的序列有點類似于 Java 流,因為它們有許多簡單地回傳另一個序列的惰性函式。
然而all,any和none立竿見影不管你是否打電話給他們一個序列或可迭代。你可以看出它們并不懶惰,因為它們回傳一個布林值而不是另一個序列,并且在他們的檔案中,它們被描述為終端,這意味著它們會立即評估和迭代序列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/409904.html
標籤:
上一篇:在API中使用setRequiredPasswordComplexity(passwordComplexity:Int)小于31
