來一個(gè)demo:帶返回函數(shù)的函數(shù)
data class Person (
val firstName :String,
val lastName :String,
val phoneNumber:String?
)
class ContactListFilters{
var prefix:String=""
var onlyWithNumber:Boolean=false
fun getPredicate():(Person) -> Boolean{
val startsWithPrefix={
p: Person ->
p.firstName.startsWith(prefix)||p.lastName.startsWith(prefix)
}
if (!onlyWithNumber){
return startsWithPrefix
}
return {
startsWithPrefix(it) && it.phoneNumber!=null
}
}
}
fun main(args: Array<String>) {
val contacts= listOf(Person("dsfd","ddfs","112233"),
Person("kjk","wqrre","65644"),
Person("awqq","pioi",null)
)
val contactListFilters=ContactListFilters()
with(contactListFilters){
prefix="kj"
onlyWithNumber=true
}
println(contacts.filter(
contactListFilters.getPredicate()
))
}
Lambda篩選demo
/**
*
* @author ll
* @Description:記錄站點(diǎn)數(shù)據(jù)
* @date Created in 2018/04/07 09:55 AM
*/
data class SiteVisit (
val path:String,//路徑
val duration:Double,//訪問時(shí)長
val os:OS //系統(tǒng)
)
enum class OS{
WINDOWS,LINUX,MAC,IOS,ANDROID
}
計(jì)算Windows時(shí)間
val log= listOf(
SiteVisit("/",34.0,OS.WINDOWS),
SiteVisit("/dfdf",22.0,OS.MAC),
SiteVisit("/dfgg",12.0,OS.WINDOWS),
SiteVisit("/ryyy",8.0,OS.IOS),
SiteVisit("/wtyty",16.3,OS.ANDROID)
)
//Windows平均訪問時(shí)間
val avgWindows=log
.filter { it.os==OS.WINDOWS }
.map (SiteVisit::duration )
.average()
println(avgWindows)
抽取公共函數(shù):
fun List<SiteVisit>.avgDurationFor(os:OS)=
filter { it.os==os }
.map (SiteVisit::duration)
.average()
//Windows
println(log.avgDurationFor(OS.WINDOWS))
只要移動(dòng)平臺(tái)(Android 和 IOS數(shù)據(jù))
val avgMobilePlatform=log
.filter { it.os in setOf(OS.IOS,OS.ANDROID) }
.map (SiteVisit::duration)
.average()
println(avgMobilePlatform)
顯然需要更新公共函數(shù)了
fun List<SiteVisit>.avgDuration(predicate: (SiteVisit) -> Boolean)=
filter(predicate)
.map(SiteVisit::duration)
.average()
測試:
//Windows
println(log.avgDuration { it.os==OS.WINDOWS })
//mobile platform
println(log.avgDuration { it.os==OS.IOS || it.os ==OS.ANDROID })
println(log.avgDuration { it.os==OS.IOS && it.path =="/ryyy" })
內(nèi)聯(lián)函數(shù)inline:消除lambda的開銷
inline fun<T> synchronized(lock: Lock, action:() ->T) :T{
lock.lock()
try {
return action()
} finally {
lock.unlock()
}
}
fun foo(l:Lock){
println("before sync")
synchronized(l){
println("Action")
}
println("after action")
}
/**
*函數(shù)類型做參數(shù)鞠绰,不是lambda蜈膨,inline失效
*/
class LockOwner(val lock:Lock){
fun runUnderLock(body:() ->Unit){
synchronized(lock,body)
}
}
class LockOwner2(val lock:Lock){
fun _runUnderLock_(body: () -> Unit){
lock.lock()
try {
body()
} finally {
lock.unlock()
}
}
}
kotlin中牺荠,filter,map函數(shù)被聲明為內(nèi)聯(lián)函數(shù)灶壶。當(dāng)出現(xiàn)大量數(shù)據(jù)處理時(shí)驰凛,可以通過 在鏈?zhǔn)胶蠹觓sSequence()担扑,用序列代替集合,但kotlin建議在處理大數(shù)據(jù)時(shí)用胚宦。
inline只能提高帶有l(wèi)ambda參數(shù)的函數(shù)的性能.
java中try-with-resources在kotlin中的替代燕垃。
//java代碼
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader bufferedReader=new BufferedReader(new FileReader(path))){
return bufferedReader.readLine();
}
}
//kotlin中使用use代替卜壕,use在kotlin中是內(nèi)聯(lián)函數(shù)
fun readFirstLineFromFile(path:String):String{
BufferedReader(FileReader(path)).use {
br -> return br.readLine()
}
}
lambda中的返回語句
data class Person2(val name: String ,val age:Int)
fun lookFofJim(people :List<Person2>){
for (person in people){
if (person.name=="Jim") {
println("找到了")
return
}
}
println("jim 沒找到")
}
fun main(args: Array<String>) {
val people= listOf(Person2("fdaaf",34), Person2("trrt",73))
lookFofJim(people)
}
forEach依舊適用
people.forEach {
if (it.name=="Jim") {
println("找到了")
return
}
}
引入便簽局部返回:@一定要有轴捎,邊簽名任意
fun lookFofJim2(people :List<Person2>){
people.forEach label@{
if (it.name=="Jim") {
println("找到了")
return@label
}
}
//總會(huì)執(zhí)行
println("jim ...")
}
函數(shù)名也可以作為標(biāo)簽
fun lookFofJim(people :List<Person2>){
/* for (person in people){
if (person.name=="Jim") {
println("找到了")
return
}
}
*/
people.forEach {
if (it.name=="Jim") {
println("找到了")
return@forEach
}
}
println("jim 沒找到")
}
注意,當(dāng)匿名函數(shù)中有return時(shí)昨悼,返回最近的匿名函數(shù)
fun lookFofJim3(people :List<Person2>){
people.forEach(fun(person) {
if (person.name=="trrt") {
println("找到了")
return
}
})
//總會(huì)執(zhí)行
println("jim ...")
}
此時(shí)return是從fun(person)返回率触。
泛型:Kotlin泛型要求類型實(shí)參被顯示地說明汇竭,或者能被編譯器推導(dǎo)出來。
fun <T : Number> oneHalf(value :T) :Double{
return value.toDouble()/2.0
}
val nums= oneHalf(65.32)
println(nums)
fun <T: Comparable<T>> max (first:T,second:T):T{
return if (first>second) first else second
// return if (first.compareTo(second)>0) first else second
}
println(max(23,546))
參數(shù)約定:
fun<T> ensureTrailingPeriod(seq:T) where T:CharSequence,T:Appendable{
if(!seq.endsWith('.')){
seq.append('.')
}
}
val hello=StringBuilder("fafd fafddadf hello")
ensureTrailingPeriod(hello)
println(hello)
形參可空
class Processor<T> {
fun process(value :T){
value?.hashCode()
}
}
val nullProcess=Processor<String?>()
nullProcess.process(null)
Any代替Any皂甘?形參非空
class Processor2<T : Any>{
fun process(value : T){
value.hashCode()
}
}
聲明帶實(shí)例化參數(shù)的函數(shù)
inline fun <reified T> isA(value: Any) =value is T
println(isA<String>("ffdafadfadfadfadfd"))
結(jié)果:true
標(biāo)準(zhǔn)庫函數(shù):filterIsInstance
val items= listOf("faafd","fdf",122,"fddf1","113423")
println(items.filterIsInstance<String>())
關(guān)于reified悼凑。帶reified類型參數(shù)的inline函數(shù)不能再java中調(diào)用户辫。普通的inline可以被調(diào)用,但不能被內(nèi)聯(lián)墓塌。
filterIsInstances被標(biāo)記為inline奥额,但它并不期望lambda作為實(shí)參 垫挨。
目前,還不能把類伞梯,屬性和非內(nèi)聯(lián)函數(shù)的類型參數(shù)標(biāo)記為reified帚屉。當(dāng)lambda因?yàn)樾阅鼙粌?nèi)聯(lián)時(shí)漾峡,可以使用noinline標(biāo)記生逸。
.
inline fun<reified T : Activity> Context.startActivity(){
val intent= Intent(this,T::class.java)
startActivity(intent)
}
Handler().postDelayed({
startActivity<MainActivity>()
},3000)
一個(gè)編譯器通過不了的demo
fun addAnswer(list: MutableList<Any>){
list.add(43)
}
val strings= mutableListOf("adf","dfadf")
addAnswer(strings)
kotlin中List是只讀集合
超類型概念:A是B的子類型,那么B就是A的超類型烙无。
非空類型A是可空類型A?的子類型嘹朗,但反過來不是饶辙。
不變型:對(duì)于任意類型A和B迂苛,MutableList<A>既不是MutableList<B>的子類型,也不是超類型三幻,它就被稱為該類型參數(shù)是不變型的。
協(xié)變:如果A是B的子類型抑堡,那么List<A>是List<B>的子類型夷野,這樣的類或者接口被稱為協(xié)變荣倾。聲明協(xié)變用out關(guān)鍵字。
逆變:反轉(zhuǎn)子類型化關(guān)系妒貌。in關(guān)鍵字灌曙。
interface Produce<out T>{
fun produce():T
}
interface Function1<in p,out R>{
operator fun invoke(p:p) :R
}