1. 程式人生 > 其它 >Kotlin行內函數、高階API學習

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謝謝。