Android - 일반적인 구문 및 키워드와 람다

Kotlin 공통 함수 및 키워드

1 . if 문

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

2 .언제

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

3 . is 키워드는 유형 일치의 핵심이며 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. 생성자 보조 생성자

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. 데이터 데이터 클래스는 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.목록

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

11. 지도

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.람다
val maxLengthFruit = list.maxBy { fruit -> fruit.length }
13.  필터 기능
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.  지도 기능
fun main() {
    val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")    
    val newList = list.map { 
        it.toUpperCase()
     }
    for (fruit in newList) {
        println(fruit)
    }
 }
15.  모든 기능
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 {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. 기능 포함

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. 실행 기능

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. 적용 기능

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 어노테이션은 싱글톤 클래스나 컴패니언 객체의 메소드에만 추가할 수 있으며 일반 메소드에 추가하려고 하면 바로 구문 오류가 발생합니다.

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

26.반복 기능

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.라티니트

지연된 초기화는 비워둘 필요가 없습니다.

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는 레이아웃 파일에서 Fragment 인스턴스를 얻는 데 특별히 사용되는 findViewById()와 유사한 메서드를 제공합니다.

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에 포함, kotlin은 포함

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

33. 내부 내부 클래스 정의 방법

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

 36. 노인라인 함수

예를 들어 고차 함수가 두 개 이상의 함수 유형 매개변수를 수신하고 함수에 inline 키워드를 추가하면 Kotlin 컴파일러는 참조된 모든 Lambda 표현식을 자동으로 인라인합니다. 하지만 람다 식 중 하나만 인라인하려면 어떻게 해야 할까요? 그런 다음 noinline 키워드를 사용할 수 있습니다.

인라인 재미 inlineTest(block1: () -> 단위, noinline block2: () -> 단위) { }

여기서 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. 기능별 위임

예:

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

여기서 우리는 helloWorld() 메서드를 추가하고 항상 false를 반환하도록 isEmpty() 메서드를 다시 작성했습니다. 이것은 물론 잘못된 접근 방식입니다. 여기서는 데모용입니다. 이제 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. 스레드 사용(하위 스레드)

//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.비동기태스크

/**在这个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()

Supongo que te gusta

Origin blog.csdn.net/m0_59482482/article/details/129534089
Recomendado
Clasificación