Kotlin行內函數、高階API學習
Kotlin 再次學習1
行內函數
行內函數大概有幾個
- also
- apply
- run
- let
- with
- also、apply是返回物件本身
- run,let,with是返回函式閉包中最後執行的值
with
使用with的最大作用就是能夠預設使用this來進行指代,讓程式碼的可讀性可能會更好
val dialog=with(AlertDialog.Builder(this)) { // this:AlertDialog.Builder this.setTitle("hello") this.setIcon(R.drawable.ic_launcher_background) this.setMessage("message") this.create() } //此時,dialog為AlertDialog物件
也就是with中的物件是什麼,那麼this也指代什麼。一般可以在初始化的時候進行使用。
inline fun <T, R> with(receiver: T, block: T.() -> R): R
apply
apply為一個擴充套件方法,就是在原有的基礎上,進行內部變數的一些設定。可以和with相互轉換,上述的例子轉換成為apply後變成如下的程式碼。
val dialog=AlertDialog.Builder(this).apply { // this:AlertDialog.Builder this.setTitle("hello") this.setIcon(R.drawable.ic_launcher_background) this.setMessage("message") //如果要返回,寫在此處的返回為AlertDialog.Builder物件 }.create() //此時dialog是AlertDialog物件
run
run方法也是一個擴充套件方法。比如一個物件使用了run方法後,就會依次執行run方法中的方法,然後返回最後執行的方法的返回值
val dialog=AlertDialog.Builder(this).run {
// this:AlertDialog.Builder
this.setTitle("hello")
this.setIcon(R.drawable.ic_launcher_background)
this.setMessage("message")
this.create()
}
// 此處dialog是AlertDialog物件
also
also,可以理解為是let和apply函式的加強版。和apply一致,返回值是該函式的接收者。
val dialog=AlertDialog.Builder(this).also {
// it:AlertDialog.Builder
it.setTitle("hello")
it.setIcon(R.drawable.ic_launcher_background)
it.setMessage("message")
}.create()
//此時,dialog物件為AlertDialog物件
let
let可以用來判空,與apply不同的是返回值。let返回的是閉包裡面的值,apply返回的是原來的物件。
val dialog=AlertDialog.Builder(this).let {
// it:AlertDialog.Builder
it.setTitle("hello")
it.setIcon(R.drawable.ic_launcher_background)
it.setMessage("message")
it.create()
}
//此時,dialog返回的是AlertDialog物件
集合的高階函式API
高階函式大概可以有
- takeIf
- takeUnless
------這是分界線------
- map
------這是分界線------
- filter
- filterNot
- filterNotNull
------這是分界線------
- count
------這是分界線------
- sum
------這是分界線------
- fold
- reduce
------這是分界線------
- groupBy
------這是分界線------
- flatMap
- flatten
takeIf
引入想要判斷一些特殊的東西,然後可以使用該返回型別進行let。當接收到某些滿足的條件的時候,takeIf後的東西才會繼續執行。
val correctResult=a.takeIf{it>10}.let{it+10}
//此時判斷a是否大於10,如果大於10,那麼加上10
takeUnless
與takeIf相反,當條件結果不滿足的時候,也就是takeUnless中為false是,才會執行後面的東西。
val correctResult=a.takeUnless{it>10}.let{it+10}
//此時判斷a是否大於10,如果小於10,那麼加上10
map
map方法接收到了一個函式,這個函式對集合中的每一個元素進行操作,然後將操作進行結果返回,最後產生了一個由這些結果組成的集合。
val list= arrayOf(1,2,3,4,5,6,7,8,9)
val newList=list.map { it*10 }
此時在newList中,存在著list中的所有元素乘以10後的元素。
使用map的話,可以免去了for語句,同時也可以避免中間變數的定義。
filter
對於這個函式,可以用來篩選一些東西。對於滿足條件filter{條件}的內容,就會進行塞選,從而保留下來,組成一個新的集合。
val list= arrayOf(1,2,3,4,5,6,7,8,9)
val newList=list.filter {it>5}
此時,newList中會存在大於5的集合,也就是newList=[6 7 8 9]
filterNot
這個與filter的作用相反,如果使用該行內函數,那麼將會過濾掉與條件值不同的東西。
val list= arrayOf(1,2,3,4,5,6,7,8,9)
val newList=list.filter {it>5}
此時,newList中會存在小於等於5的集合,也就是newList=[1 2 3 4 5]
filterNotNull
這個是用來過濾掉值為null元素
count
用來統計符合條件的個數
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listCount=list.count {it==4}
在list集合中,統計值等於4的集合個數有多少個
sum
該方法用來進行求和,之前還有sumBy方法,但是該方法已經被廢除。
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listSum=list.sum()
此時listSum=36
fold
fold需要接入的引數有兩個,第一個一般為initial,也就是初始值。第二個引數為一個函式,該函式為當前便利到的集合元素。每一次都掉用這個函式,然後將產生的結果作為引數提供給下一次的掉用
第二個函式為operation: (acc: R, T) -> R
,此時,第一個引數為每次執行該函式後的返回結果,第二個引數為其他元素。
使用fold行內函數的時候,能夠體現到了遞迴的思想。
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listSum=list.fold(0){ result,pos-> result+pos }
上述程式碼為求list中每個元素的總和,設定了初始值為0。如果list中沒有元素,那麼直接返回初始值,也就是0這個結果
reduce
reduce函式只是需要傳入一個函式,函式的實現形式也與fold類似。只不過reduce無需傳入初始值。
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listSum=list.reduce{ result,pos-> result+pos }
該例子也是求和。但是當list中沒有元素的時候,使用reduce會進行異常的丟擲。
groupBy
這個行內函數為分類函式。例如一個物件中如果按照部分屬性進行劃分的話,可能會劃分出許多不同的集合。而groupBy這個函式就是使用來劃分不同的集合的。據一個簡單的例子
val list= arrayOf(1,2,3,4,4,4,5,6,7)
val listGroup=list.groupBy{ it }
list為一個基本的資料集合,其中僅是含有基本的資料型別。當我需要進行劃分的時候,listGroup將會變成{1=[1], 2=[2], 3=[3], 4=[4, 4, 4], 5=[5], 6=[6], 7=[7]}
。此時可以知道該列表中的具體的分類了。
flatMap
如果得到一個巢狀的集合,並且需要對這個集合進行加工,使其成為一個扁平化的集合,然後再進行加工,得到一個僅僅是單列屬性組成的集合(對應著一個data class、class而言)。此時使用行內函數flatMap可能會比較方便。
val arraylist=listOf(
listOf(Student("name1","sex1"),Student("name2","sex1"),Student("name3","sex2")),
listOf(Student("name4","sex1"),Student("name5","sex2")),
listOf(Student("name6","sex1"))
)
此時,經過處理後,如果僅僅是需要姓名一列,那麼可以使用flatMap,例子如下
val arrayname=arraylist.flatMap{it.name}
此時arrayname的值便成為了
arrayname=["name1","name2","name3","name4","name5","name6"]
flatten
對於一個巢狀集合,如果想要經過處理,變成一個純粹是一維的一個集合,可以使用這個行內函數,從而進行快速的轉換。
也是上面的例子,如果需要得到一個數組中都是Student這個物件的集合,那麼使用該函式即可
val array=arraylist.flatten()
此時,array就成為了
array=[Student("name1","sex1"),Student("name2","sex1"),Student("name3","sex2"),Student("name4","sex1"),Student("name5","sex2"),Student("name6","sex1")]
這是小睿的部落格,如果需要轉載,請標註出處啦~ヾ(≧▽≦*)o謝謝。