Item 54: Limit the number of operations
這個要點,要直翻比較沒這麼傳神,為好懂一點,改成這個標題
每一個集合處理方法都是一個成本。對於標準的集合處理,其成本包括:
對於序列 (Sequence) 處理,其成本是
這些成本通常都很小,但它們與元素數量成正比。所以,對於大型集合,這樣的成本可能變得很明顯。限制這些成本的最基本方法之一是使用複合的操作。例如,不是先過濾非空值再轉換為非空值型別,我們使用 filterNotNull。或者,不是map 轉換後過濾出空值,我們可以直接使用 mapNotNull。
// Works
fun List<User>.getNames(): List<String> =
this.map { it.name }
.filter { it * null }
.map { it }
// Better
fun List<User>.getNames(): List<String> =
this.map { it.name }
.filterNotNull()
// Best
fun List<User>.getNames(): List<String> =
this.mapNotNull { it.name }
最大的問題不是誤解這些改變的重要性,而是我們缺乏知識,不知道應該使用哪些高階集合處理函式。這也是為什麼學習它們是有益的另一個原因。此外,IntelliJ 或是 Android Studio 的警告也會提供幫助,它們經常建議更好的替代方法
不過,這些建議還是有限,可以透過記憶或印象回來看這張表。以下是一些常見的函式呼叫及限制操作數量的替代方法列表
可優化對象 | 建議使用 |
---|---|
.filter { it != null }.map { it!! } |
.filterNotNull().map { it!! } |
.map { <Transformation> }.filterNotNull () |
mapNotNull { ‹Transformation> } |
.map { <Transformation> }.joinToString() |
.joinToString { <Transformation> } |
.filter { ‹Predicate 1> }.filter { <Predicate 2> } |
.filter { <Predicate 1> && <Predicate 2> } |
.filter { it is Type }.map { it as Type } |
.filterIsInstance<Type>() |
.sortedBy { <Key 2> }.sortedBy { <Key 1> } |
.sortedWith (compareBy { <Key 1> }, { <Key 2> 1)) |
.listOf (...).filterNotNull () |
.listOfNotNull (...) |
withIndex().filter { (index, elem) -> <Predicate using index> }.map { it.value} |
.filterIndexed { index, elem -> <Predicate using index> } (Similarly for map, forEach, reduce and fold) |
大多數的集合處理步驟需要對整個集合進行迭代和中間集合的建立。這個成本可以通過使用更合適的集合處理高階函式來減少。
年初(G)-IDLE有來台灣的紅白。高人氣!!