拓展函数
1 2 3 4 5 6 7 8 9 10 11 fun String.addExt (amount:Int =1 ) = this + " !" .repeat(amount)fun Any.easyPrint () = println(this ) fun main () { println("abc" .addExt(2 )) "abc" .easyPrint() 15. easyPrint() }
类型别名 typealias 如果类型名称太长,你可以另外引入较短的名称,并使用新的名称替代原类型名。
https://www.kotlincn.net/docs/reference/type-aliases.html
泛型拓展函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 fun String.addExt (amount:Int =1 ) = this + " !" .repeat(amount)fun <T> T.easyPrint () :T{ println(this ) return this } fun main () { "abc" .addExt(2 ).easyPrint() 15. easyPrint() 15. also { } val let = "abc" .let { 50 } }
Let源码 1 2 3 4 5 6 7 8 public inline fun <T, R> T.let (block: (T ) -> R ) : R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block(this ) }
拓展属性 给String类添加一个拓展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 fun String.addExt (amount: Int = 1 ) = this + " !" .repeat(amount)val String.numVowels get () = count { "aeiou" .contains(it) } fun <T> T.easyPrint () : T { println(this ) return this } fun main () { "abc" .addExt(2 ).easyPrint() "The people's Republic of China" .numVowels.easyPrint() }
可空类拓展 可以定义拓展函数用于可空类型,在可空类型上定义拓展函数,你可以直接在拓展函数体内借鉴可能出现的空值问题。
1 2 3 4 5 6 7 8 fun String?.printWithDefault (default:String ) =print(this ?: default) fun main () { val nullableString:String? = "hehe" nullableString.printWithDefault("abc" ) }
Infix
1 2 3 4 5 6 7 8 9 10 infix fun String?.printWithDefault (default:String ) =print(this ?: default) fun main () { val nullableString:String? = "hehe" nullableString.printWithDefault("abc" ) nullableString printWithDefault "abc" "girl" .to(18 ) mapOf("girl" to 18 ) }
1 2 public infix fun <A, B> A.to (that: B ) : Pair<A, B> = Pair(this , that)
定义拓展文件 1 2 3 4 5 6 7 8 9 10 11 package com.util.kotin.extensionfun <T> Iterable<T> .randomTake () : T = this .shuffled().first()fun main () { var list = listOf("Jack" , "Json" , "John" ) var set = listOf("Jack" , "Json" , "John" ) list.shuffled().first() list.randomTake() }
重命名拓展 1 2 3 4 5 6 7 8 9 import com.util.kotin.extension.randomTake as Randomizerfun main () { var list = listOf("Jack" , "Json" , "John" ) var set = listOf("Jack" , "Json" , "John" ) list.shuffled().first() list.Randomizer() }
Apply源码 T.()什么意思
这个就是 带接收者的函数字面量,拓展函数里自带了接收者对象的this隐式调用
1 2 3 4 5 6 public inline fun <T> T.apply (block: T .() -> Unit ) : T { block() return this } T.() -> Unit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 import java.io.Filefun String.addExt () = " !" .repeat(this .count())fun <T> T.easyPrint () : Unit = println(this )public inline fun <T> T.apply (block: T .() -> Unit ) : T { block() return this } fun main () { val file = File("xx" ).apply { this .setReadable(true ) } val file = File("xx" ).apply { this .setReadable(true ) } fun File.ext () : Unit { setReadable(true ) } val block = File::ext File("xxx" ).apply { block } doSomething { goFix() } "abcefg" .addExt().easyPrint() "abc" .apply { } } fun doSomething (fix: () -> Unit ) { fix } fun goFix () : Unit { "goFxi" }
案例LoginModel.kt 1 2 3 4 RpcExpress.pack { request.mobileNo = mobileNo request.metaInfo = metaInfo }
1 2 3 4 5 6 7 8 inline fun <reified T : RpcRequest, reified R : RpcResult, reified E : RpcTask> pack ( build: RpcPackage <T , R, E>.() -> Unit ): RpcExecutor<T, R, E> { val rpcPackage = RpcPackage<T, R, E>(T::class .java.newInstance(), R::class .java, E::class .java) build(rpcPackage) return this .pack(rpcPackage) }
函数式编程
函数类别
Map变换
1 2 3 4 5 6 7 8 9 val animals = listOf("zebra" , "giraffe" , "elephant" , "rat" )val banies = animals.map { animal -> "A baby $animal " }.map { baby -> "$baby , with the cutest little tail ever!" } println(animals) println(banies)
1 2 val animalsLength = animals.map { it.length }println(animalsLength)
flatMap faltMap函数操作一个集合的集合,将其中多个集合中的元素的合并 后返回一个包含所有元素的单一集合。
1 2 val result = listOf(listOf(1 , 2 , 3 ), listOf(4 , 5 , 6 )).flatMap { it }println(result)
过滤
1 2 3 4 val result = listOf("Jack" ,"Jimmy" ,"Rose" ,"Tom" ).filter { it.contains("J" ) } println(result)
1 2 3 4 5 6 7 val items = listOf( listOf("rea apple" , "green apple" , "blue apple" ), listOf("red fish" , "blue fish" ), listOf("yellow banana" , "teal banana" ) ) val redItems = items.flatMap { it.filter { it.contains("red" ) } }println(redItems)
找素数 找素数,除了1和它本身,不能被任何数整除的数。
1 2 3 4 5 6 7 val numbers = listOf(7 , 4 , 8 , 4 , 3 , 22 , 18 , 11 )val primes = numbers.filter { number -> (2 until number).map { number % it }.none { it == 0 } } println(primes)
合并 合并是函数式编程的第三大类函数,合并能将不同的集合合并成一个新的集合。这个接收者是包含集合的的集合的flatmap函数不同。
zip 1 2 3 4 5 val list1 = listOf("jon" , "john1" , "john2" )val list2 = listOf("l1" , "l2" , "l3" )val toMap = list1.zip(list2).toMap()println(toMap)
{jon=l1, john1=l2, john2=l3}
Fold 可以用来合并值的合并函数是fold,这个合并函数接受一个初始累加器值,随后会根据匿名函数的结构更新 。
fold(0) accumulator从0开始
1 2 3 4 5 6 val foldedValue = listOf(1 , 2 , 3 , 4 ).fold(0 ) { accumulator, number -> println("Accmulator value: $accumulator " ) accumulator + (number * 3 ) } println("Find value: $foldedValue " )
Accmulator value: 0 Accmulator value: 3 Accmulator value: 9 Accmulator value: 18 Find value: 30
序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 fun Int .isPrime () : Boolean { (2 until this ).map { if (this % it == 0 ) { return false } } return true } fun main () { val toList = (1. .5009 ).toList().filter { it.isPrime() }.take(1000 ) println(toList.size) val oneThousandPrimes = generateSequence(2 ) { value -> value + 1 }.filter { it.isPrime() }.take(1000 ) println(oneThousandPrimes.toList().size) }
互操作性与可空性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Jhava { private int hitPoints = 3232320 ; public int getHitPoints () { System.out.println("----hitPoints-----" ); return hitPoints; } public String utterGreeting () { return "HELLO" ; } public static void main (String[] args) { } @Nullable public String determineFriends () { return null ; } }
1 2 3 4 5 6 7 8 9 fun main () { val adversary = Jhava() println(adversary.utterGreeting()) println(adversary.hitPoints) }
HELLO —-hitPoints—– 3232320
@JvmName注解指定编译类的名字
1 2 3 4 5 @file:JvmName ("Hero" )import senior.Jhavafun makeProclamation () = "Greetings , beast!"
@JvmField
1 2 3 4 5 6 class SpellBook { val spells = listOf("Magic Ms . L" , "Lay onHans" ) @JvmField val spells1 = listOf("Magic Ms . L" , "Lay onHans" ) }
1 2 3 4 SpellBook spellBook = new SpellBook(); List<String> spells = spellBook.getSpells(); List<String> spells1 = spellBook.spells1;
@JvmOverloads 1 2 3 4 5 @JvmOverloads fun handoverFood (leftHand: String = "berries" , rightHand: String = "beef" ) { println("Mmmm... you hand over some delicious $leftHand and $rightHand " ) }
可以看到编译器默认对类添加了重载
1 2 3 4 5 6 7 8 9 @JvmOverloads public static final void handoverFood(@NotNull String leftHand) { handoverFood$default(leftHand, (String)null , 2 , (Object)null ); } @JvmOverloads public static final void handoverFood() { handoverFood$default((String)null , (String)null , 3 , (Object)null ); }
但是代码中我获取不到 Herokt 类。
https://www.bilibili.com/video/BV1wf4y1s7TG?p=144&spm_id_from=pageDriver
@JvmStatic @JvmField注解还能用来以静态方式提供伴生对象里定义的值
@JvmStatic注解的作用类似于@JvmField, 允许你直接调用伴生对象里的函数
1 2 3 4 5 6 7 8 class SpellBook { companion object { @JvmField val MAX_SPELL_COUNT = 10 fun getSpellbookGreeting () = println("I am the Great man!" ) } }
加了@JvmField注解 就不用加 Companion调用
1 2 3 4 5 SpellBook.Companion.getSpellbookGreeting(); int maxSpellCount = SpellBook.MAX_SPELL_COUNT;
@Throws
1 2 3 4 5 6 public class Jhava { public void extendHandInFriendship () throws IOException { throw new IOException(); } }
Java异常 java处理 1 2 3 4 5 6 try { new Jhava().extendHandInFriendship(); } catch (IOException e) { e.printStackTrace(); }
Java异常 kotlin处理 Hero.kt
1 2 3 4 5 try { adversary.extendHandInFriendship() }catch (e:Exception){ println("exception" ) }
kotlin异常Java处理
Hero.kt
1 2 3 fun acceptApology () { throw IOException() }
1 2 3 4 5 try { HeroKt.acceptApology(); } catch (IOException e) { e.printStackTrace(); }
编译器把kotlin转成了Throwable
1 2 3 public static final void acceptApology () { throw (Throwable)(new IOException()); }
所以catch Throwable异常没问题
1 2 3 4 5 try { HeroKt.acceptApology(); } catch (Throwable e) { e.printStackTrace(); }
添加throws注解处理 1 2 3 4 @Throws(IOException::class) fun acceptApology1() { throw IOException() }
1 2 3 4 5 try { HeroKt.acceptApology1(); } catch (IOException e) { e.printStackTrace(); }
Function
1 2 3 4 5 var translator : (String)->Unit = { utterance: String -> println(utterance.toLowerCase().capitalize()) }
1 2 Function1<String, Unit> translator = HeroKt.getTranslator(); translator.invoke("TRUECE");