Android - 常用语法以及关键字以及lambda

Kotlin常用函数以及关键字

1.If语句

fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) num1 else num2

2.When

fun getScore(name: String) = when (name){
"Tom" -> 86
"Jim" -> 77
"Jack" -> 95
"Lily" -> 100
else -> 0
}

3.is关键字就是类型匹配的核心,它相当于J于Java中的instanceof关键字

fun checkNumber(num: Number) {
when (num) {
is Int -> println("number is Int")
is Double -> println("number is Double")
else -> println("number not support")}}

4.for

for (i in 0..10) {println(i)}
///until替代..关键字,你就会发现最后一行10不会再打印出来了。

///downTo降序的区间

for (i in 10 downTo 1) {println(i)}

5.open允许类被继承

class Student : Person() {

var sno = ""
var grade = 0

}

6. init所有主构造函数中的逻辑都可以写在里面

class Student(val sno: String, val grade: Int) : Person() {
init {
    println("sno is " + sno)
    println("grade is " + grade)}
}

7. constructor 次构造函数

class Student(val sno: String, val grade: Int, name: String, age: Int) :Person(name, age) {
    constructor(name: String, age: Int) : this("", 0, name, age) {
    }
    constructor() : this("", 0) {
}}

8.data数据类 无需实现toString等

data class Cellphone(val brand: String, val price: Double)

fun main() {
    val cellphone1 = Cellphone("Samsung", 1299.99)
    val cellphone2 = Cellphone("Samsung", 1299.99)
    println(cellphone1)    
    println("cellphone1 equals cellphone2 " + (cellphone1 == cellphone2))
}

9.单例模式

object Singleton {

fun singletonTest() {

println("singletonTest is called.")

}}

10.list

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")

11. Map

val map = HashMap<String, Int>()
    map["Apple"] = 1map["Banana"] = 2map["Orange"] = 3map["Pear"] = 4map["Grape"] = 5

简化val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)


for ((fruit, number) in map) {
    println("fruit is " + fruit + ", number is " + number)
}
12.Lambda
val maxLengthFruit = list.maxBy { fruit -> fruit.length }
13. filter函数
fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val newList = list.filter { 
        it.length <= 5 }.map {
         it.toUpperCase() 
    }
    for (fruit in newList) {
    println(fruit)
14. map函数
fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")    
    val newList = list.map { 
        it.toUpperCase()
     }
    for (fruit in newList) {
        println(fruit)
    }
 }
15. any和all函数
fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val anyResult = list.any { 
        it.length <= 5 
    }
    val allResult = list.all {
     it.length <= 5
     }
    println("anyResult is " + anyResult + ", allResult is " + allResult)
}
16. Thread
Thread {println("Thread is running")}.start()
17. ?.判空
if (a != null) {
    a.doSomething()
}
a?.doSomething()
val c = if (a ! = null) {
    a
} 
    else {
    b
}
18. 点击事件
aaa.setOnClickListener({

})

19.?:

val c = if (a ! = null) {a} else {b}

20. let函数

obj.let { 
    obj2 ->
    // 编写具体的业务逻辑
}

fun doStudy(study: Study?) {
    study?.let {
    it.readBooks()it.doHomework()
    }
}

21.!!.

aaa!!.
//!!.的意思是这个参数如果为空,就抛出异常

22.with函数

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
val result = with(StringBuilder()) {
 append("Start eating fruits.\n")
 for (fruit in list) {
 append(fruit).append("\n")
 }
 append("Ate all fruits.")
 toString()
}
println(result)

23.run函数

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
val result = StringBuilder().run {
 append("Start eating fruits.\n")
 for (fruit in list) {
 append(fruit).append("\n")
 }
 append("Ate all fruits.")
 toString()
}
println(result)

24.apply函数

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
val result = StringBuilder().apply {
 append("Start eating fruits.\n")
 for (fruit in list) {
 append(fruit).append("\n")
 }
 append("Ate all fruits.")
}
println(result.toString())

25.静态方法@JvmStatic

@JvmStatic注解只能加在单例类或companion object中的方法上,如果你尝试加在 一个普通方法上,会直接提示语法错误。

class Util {
 fun doAction1() {
 println("do action1")
 }
 companion object {
 @JvmStatic
 fun doAction2() {
 println("do action2")
 }
 }
}

26.repeat函数

repeat函数是Kotlin中另外一个非常常用的标准函数,它允许你 传入一个数值n,然后会把Lambda表达式中的内容执行n遍。

class MainActivity : AppCompatActivity() {
 private val fruitList = ArrayList<Fruit>()
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 initFruits() // 初始化水果数据
 val adapter = FruitAdapter(this, R.layout.fruit_item, fruitList)
 listView.adapter = adapter
 }
 private fun initFruits() {
 repeat(2) {
 fruitList.add(Fruit("Apple", R.drawable.apple_pic))
 fruitList.add(Fruit("Banana", R.drawable.banana_pic))
 fruitList.add(Fruit("Orange", R.drawable.orange_pic))
 fruitList.add(Fruit("Watermelon", R.drawable.watermelon_pic))
 fruitList.add(Fruit("Pear", R.drawable.pear_pic))
 fruitList.add(Fruit("Grape", R.drawable.grape_pic))
 fruitList.add(Fruit("Pineapple", R.drawable.pineapple_pic))
 fruitList.add(Fruit("Strawberry", R.drawable.strawberry_pic))
 fruitList.add(Fruit("Cherry", R.drawable.cherry_pic))
 fruitList.add(Fruit("Mango", R.drawable.mango_pic))
 }
 }
www.blogss.cn
}

27.lateinit

延时初始化 不用判空

28.密封类

sealed class Result
class Success(val msg: String) : Result()
class Failure(val error: Exception) : Result()

//其他类
fun getResultMsg(result: Result) = when (result) {
 is Success -> result.msg
 is Failure -> "Error is ${result.error.message}"
}

29.Fragment和Activity之间进行交互,FragmentManager提供了一个类似于 findViewById()的方法,专门用于从布局文件中获取Fragment的实例

val fragment = supportFragmentManager.findFragmentById(R.id.leftFrag) as LeftFragment
//简化
val fragment = leftFrag as LeftFragment

30.Fragment中又该怎样调用Activity 里的方法

if (activity != null) {
 val mainActivity = activity as MainActivity
}

31.扩展函数

fun String.lettersCount(): Int {
 var count = 0
 for (char in this) {
 if (char.isLetter()) {
 count++
 }
 }
 return count
}
//调用
val count = "ABC123xyz!@#".lettersCount()

32.java中contains,kotlin为 in

//java
if ("hello".contains("he")) {
}
//kotlin
if ("he" in "hello") {
}

33.inner 内部类定义方式

class MainActivity : AppCompatActivity() {
 lateinit var timeChangeReceiver: TimeChangeReceiver
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 val intentFilter = IntentFilter()
 intentFilter.addAction("android.intent.action.TIME_TICK")
 timeChangeReceiver = TimeChangeReceiver()
 registerReceiver(timeChangeReceiver, intentFilter)
 }
 override fun onDestroy() {
 super.onDestroy()
 unregisterReceiver(timeChangeReceiver)
 }
 inner class TimeChangeReceiver : BroadcastReceiver() {
 override fun onReceive(context: Context, intent: Intent) {
 Toast.makeText(context, "Time has changed", Toast.LENGTH_SHORT).show()
 }
 }
}
//解开注册
onDestroy()
unregisterReceiver()

34.高阶函数

//kotlin
fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
 val result = operation(num1, num2)
 return result
}
//调用
fun main() {
 val num1 = 100
 val num2 = 80
 val result1 = num1AndNum2(num1, num2) { n1, n2 ->
 n1 + n2
 }
 val result2 = num1AndNum2(num1, num2) { n1, n2 ->
 n1 - n2
 }
 println("result1 is $result1")
 println("result2 is $result2")
}
//java代码实现原理
public static int num1AndNum2(int num1, int num2, Function operation) {
 int result = (int) operation.invoke(num1, num2);
 return result;
}
public static void main() {
 int num1 = 100;
 int num2 = 80;
 int result = num1AndNum2(num1, num2, new Function() {
 @Override
 public Integer invoke(Integer n1, Integer n2) {
 return n1 + n2;
 }
 });
}
/**考虑到可读性,我对这段代码进行了些许调整,并不是严格对应了Kotlin转换成的Java代码。可
以看到,在这里num1AndNum2()函数的第三个参数变成了一个Function接口,这是一种
Kotlin内置的接口,里面有一个待实现的invoke()函数。而num1AndNum2()函数其实就是调
用了Function接口的invoke()函数,并把num1和num2参数传了进去。
在调用num1AndNum2()函数的时候,之前的Lambda表达式在这里变成了Function接口的匿
名类实现,然后在invoke()函数中实现了n1 + n2的逻辑,并将结果返回。
这就是Kotlin高阶函数背后的实现原理。你会发现,原来我们一直使用的Lambda表达式在底层
被转换成了匿名类的实现方式。这就表明,我们每调用一次Lambda表达式,都会创建一个新
的匿名类实例,当然也会造成额外的内存和性能开销。
为了解决这个问题,Kotlin提供了内联函数的功能,它可以将使用Lambda表达式带来的运行时
开销完全消除。*/

35.内联函数 inline

只需要在定义高阶函数时加上inline关键字的声明即可

inline fun num1AndNum2(num1: Int, num2: Int, operation: (Int, Int) -> Int): Int {
 val result = operation(num1, num2)
 return result
}
//Kotlin编译器会将Lambda表达式中的代码替换到函数类型参数调用的地方

 36.noinline函数

比如,一个高阶函数中如果接收了两个或者更多函数 类型的参数,这时我们给函数加上了inline关键字,那么Kotlin编译器会自动将所有引用的 Lambda表达式全部进行内联。 但是,如果我们只想内联其中的一个Lambda表达式该怎么办呢?这时就可以使用noinline关 键字了

inline fun inlineTest(block1: () -> Unit, noinline block2: () -> Unit) { }

这里使用inline关键字声明了inlineTest()函数,原本block1和block2这两 个函数类型参数所引用的Lambda表达式都会被内联。但是我们在block2参数的前面又加上了 一个noinline关键字,那么现在就只会对block1参数所引用的Lambda表达式进行内联了。 这就是noinline关键字的作用 

为什么Kotlin还要提供一个noinline关键字来排除 内联功能呢?这是因为内联的函数类型参数在编译的时候会被进行代码替换,因此它没有真正 的参数属性。非内联的函数类型参数可以自由地传递给其他任何函数,因为它就是一个真实的 参数,而内联的函数类型参数只允许传递给另外一个内联函数,这也是它最大的局限性。

例子:

fun printString(str: String, block: (String) -> Unit) {
 println("printString begin")
 block(str)
 println("printString end")
}
fun main() {
 println("main start")
 val str = ""
 printString(str) { s ->
 println("lambda start")
 if (s.isEmpty()) return@printString
 println(s)
 println("lambda end")
 }
 println("main end")
}
/**这里定义了一个叫作printString()的高阶函数,用于在Lambda表达式中打印传入的字符串
参数。但是如果字符串参数为空,那么就不进行打印。注意,Lambda表达式中是不允许直接
使用return关键字的,这里使用了return@printString的写法,表示进行局部返回,并且
不再执行Lambda表达式的剩余部分代码。*/

但是如果我们将printString()函数声明成一个内联函数,那么情况就不一样了

inline fun printString(str: String, block: (String) -> Unit) {
 println("printString begin")
 block(str)
 println("printString end")
}
fun main() {
 println("main start")
 val str = ""
 printString(str) { s ->
 println("lambda start")
 if (s.isEmpty()) return
 println(s)
 println("lambda end")
 }
 println("main end")
}

38.委托 by函数

例:

class MySet<T>(val helperSet: HashSet<T>) : Set<T> by helperSet {
 fun helloWorld() = println("Hello World")
 override fun isEmpty() = false
}

这里我们新增了一个helloWorld()方法,并且重写了isEmpty()方法,让它永远返回 false。这当然是一种错误的做法,这里仅仅是为了演示一下而已。现在我们的MySet就成为 了一个全新的数据结构类,它不仅永远不会为空,而且还能打印helloWorld(),至于其他 Set接口中的功能,则和HashSet保持一致。这就是Kotlin的类委托所能实现的功能。

看一下委托属性的语法结构,如下所示:

class MyClass {
 var p by Delegate()
}
/**可以看到,这里使用by关键字连接了左边的p属性和右边的Delegate实例,这是什么意思呢?
这种写法就代表着将p属性的具体实现委托给了Delegate类去完成。当调用p属性的时候会自
动调用Delegate类的getValue()方法,当给p属性赋值的时候会自动调用Delegate类的
setValue()方法。
因此,我们还得对Delegate类进行具体的实现才行,代码如下所示:*/
class Delegate {
 var propValue: Any? = null
 operator fun getValue(myClass: MyClass, prop: KProperty<*>): Any? {
 return propValue
 }
 operator fun setValue(myClass: MyClass, prop: KProperty<*>, value: Any?) {
 propValue = value
 }
}

39.thread 用法(子线程)

//1、常规
class MyThread : Thread() {
  override fun run() {
  // 编写具体的逻辑
  }
}
MyThread().start()

//2、Runnable写法
class MyThread : Runnable {
  override fun run() {
  // 编写具体的逻辑
  }
}
val myThread = MyThread()
Thread(myThread).start()
//也可以变成
Thread {
 // 编写具体的逻辑
}.start()

//3、内置顶层函数
thread {
 // 编写具体的逻辑
}

40.AsyncTask

/**在这个DownloadTask中,我们在doInBackground()方法里执行具体的下载任务。这个方法
里的代码都是在子线程中运行的,因而不会影响主线程的运行。注意,这里虚构了一个
doDownload()方法,用于计算当前的下载进度并返回,我们假设这个方法已经存在了。在得
到了当前的下载进度后,下面就该考虑如何把它显示到界面上了,由于doInBackground()方
法是在子线程中运行的,在这里肯定不能进行UI操作,所以我们可以调用
publishProgress()方法并传入当前的下载进度,这样onProgressUpdate()方法就会很
快被调用,在这里就可以进行UI操作了。
当下载完成后,doInBackground()方法会返回一个布尔型变量,这样onPostExecute()方
法就会很快被调用,这个方法也是在主线程中运行的。然后,在这里我们会根据下载的结果弹
出相应的Toast提示,从而完成整个DownloadTask任务。
简单来说,使用AsyncTask的诀窍就是,在doInBackground()方法中执行具体的耗时任务,
在onProgressUpdate()方法中进行UI操作,在onPostExecute()方法中执行一些任务的收
尾工作。*/

class DownloadTask : AsyncTask<Unit, Int, Boolean>() {
     override fun onPreExecute() {
 progressDialog.show() // 显示进度对话框
     }
 override fun doInBackground(vararg params: Unit?) = try {
     while (true) {
     val downloadPercent = doDownload() // 这是一个虚构的方法
     publishProgress(downloadPercent)
     if (downloadPercent >= 100) {
     break
     }
 }
 true
     } catch (e: Exception) {
     false
 }
 override fun onProgressUpdate(vararg values: Int?) {
 // 在这里更新下载进度
 progressDialog.setMessage("Downloaded ${values[0]}%")
 }
 override fun onPostExecute(result: Boolean) {
 progressDialog.dismiss()// 关闭进度对话框
 // 在这里提示下载结果
     if (result) {
     Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show()
     } else {
     Toast.makeText(context, " Download failed", Toast.LENGTH_SHORT).show()
     }
 }
}

//启动
DownloadTask().execute()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值