Kotlin 01

1. 函数语法糖

一行,则简化之。返回类型也可以省略。

fun findMax(num1: Int, num2: Int) = max(num1, num2)

2. if 可以有返回值

返回值是每一个条件中最后一行代码的返回值。

fun findMax2(num1: Int, num2: Int): Int {
    val value = if (num1 > num2) {
        num1
    } else {
        num2
    }
    return value
}

进而可以简化成:

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

3. 条件编译 when

fun getScore(name: String) = when (name) {
    "qer" -> 100
    "yqy" -> 105
    "lby" -> 100
    else -> 0
}

fun getScore2(name: String) = when {
    name == "qer" -> 100
    name == "yqy" -> 105
    name ==  "lby" -> 100
    name.startsWith("Tom") -> 1000 // 所有Tom开头的
    else -> 0
}

4. for循环

	var range = 0..10 // [0,10]
	var range2 = 0 until 10 // [0,10)
	var range3 = 10 downTo 1 // [10,1]
	for (i in range step 2) { // i += 2
	    print(i)
	}

5. 构造函数

5.1 主构造函数

Person.kt

open class Person(val name: String, val age: Int) {
    fun eat() {
        println(name + "is eating. He/She is " + age + " years old.");
    }
}

Student.kt

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

子类中的构造函数必须调用父类中的构造函数
在主构造函数中声明成val或者var的参数将自动成为该类的字段

在默认主构造函数的时候,Person后面是空的,Student继承的时候Person后面要跟括号,就是因为Student类的主构造函数在初始化的时候会调用Person类的无参数构造函数。

5.2 次构造函数

当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)。

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);
}

类中只有次构造函数,没有主构造函数的情况:

class Student : Person {
    constructor(name: String, age: Int) : super(name, age) {
    }

    constructor() : this("", 0);
}

因为没有主构造函数,所以Person后面没有加括号
this关键字换成super好像是java中的特性

6. 接口

Student.kt

class Student(name: String, age: Int) : Person(name, age), Study {
    override fun readBooks() {
        println(name + " is reading.")
    }
}

fun main() {
    val student = Student("qer", 10)
    doStudy(student)
}

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

Study.kt

interface Study {
    fun readBooks()
    fun doHomework() {
        println("this is default implementation of doHomework()")
    }
}

doStudy() 函数接收一个Study类型的参数,由于Student类实现了Study接口,因此Student类的实例是可以传递给doStudy()函数的。

java和kotlin可见性修饰符的异同:
在这里插入图片描述

7. 数据类和单例类

7.1 数据类
data class Cellphone(val brand: String, val price: Double)

/qiang

7.2 单例类
fun main() {
    Singleton.singletonTest()
}

object Singleton {
    fun singletonTest() {
        println("singletonTest is called.")
    }
}

8. Lambda

8.1 集合的创建与遍历

set 集合底层是使用hash映射机制来存放数据的,因此集合中的元素无法保证有序。

map初始化中的to并不是关键字,而是一个infix函数。

    val list =  listOf("qer1", "qer2", "qer3")
    val list2 =  mutableListOf("qer1", "qer2", "qer3") // 这里用val 或者 var好像并没有什么影响,但是会被推荐使用 val
    list2.add("qer4")

    val set = setOf("qer1", "qer2", "qer3")
    val set2 = mutableSetOf("qer1", "qer2", "qer3")
    set2.add("qer4")

    for (per in set2) {
        println(per)
    }

    val map = mapOf<String, Int>("qer1" to 1, "qer2" to 2, "qer3" to 3)
    val map2 = mutableMapOf<String, Int>("qer1" to 1, "qer2" to 2, "qer3" to 3)
    map2["qer4"] = 4
    map2["qer5"] = 5
    for ((per, num) in map2) {
        println("${per} 's num is ${num}")
    }
8.2 集合的函数式API
maxby

Lambda表达式的语法结构:

{ 参数名1: 参数类型, 参数名2: 参数类型 -> 函数体 }

    val list3 =  listOf("qer1", "qer11111", "qer111")
    val maxQer0 = list3.maxBy({ qers: String -> qers.length }) // 持续化简变成下一行
    val maxQer = list3.maxBy { it.length }
    println(maxQer0)

几个化简的原则:

  1. 当Lambda把参数是函数的最后一个参数时,可以将Lambda表达式移到函数括号的外面
  2. 如果Lambda参数是函数的唯一一个参数的话,还可以将函数的括号省略
  3. Kotlin有出色的类型推导机制,Lambda表达式中的参数列表在大多数情况下不必声明参数类型
  4. 当Lambda表达式的参数列表中只有一个参数时,也不必声明参数名,而是可以使用it关键字来代替
map
    val newList = list3.map { it.toUpperCase() }
    for (per in newList) {
        println(per)
    }
filter
    val newFilterList = list3.filter { it.length <= 6 }
            .map { it.toUpperCase(Locale.ROOT) }
    for (per in newFilterList) {
        println(per)
    }
any & all

any:用于判断集合中是否至少存在一个元素满足指定条件
all:用于判断集合中是否所有元素都满足指定条件

    val anyResult = list3.any{ it.length <= 4 }
    val allResult = list3.all{ it.length <= 4 }
    println("${anyResult}  ${allResult}")
8.3 JAVA 函数式 API 的使用

限制条件:如果我们在 Kotlin 代码中调用了一个 Java 方法,并且该方法接收一个JAVA单抽象方法接口函数,就可以使用函数式API。Java单抽象方法接口指的是接口中只有一个待实现方法,如果接口中有多个待实现方法,则无法使用函数式 API。

    Thread( object : Runnable {
        override fun run() {
            println("Thread is running...")
        }
    }).start()

    Thread{
        println("Thread2 is running...")
    }.start()

9. 关于空指针

9.1 处理空指针

kotlin默认所有的参数和变量都不可为空
Kotlin将空指针异常的检查提前到了编译时期

可空的类型系统:类名后面加上一个问号。
?.:当对象不为空时正常调用相应的方法,当对象为空时则什么都不做
?::这个操作符左右两边都接受一个表达式,如果左边表达式的结果不为空就返回左边表达式的结果,否则就返回右边表达式的结果。
!!.:非空断言,想要强行通过编译

fun main() {
    val text: String? = null
    var x = getTextLength(text)
    println(x)
}

fun getTextLength(text: String?) = text?.length ?: 0

当text为空时,text?.lenght会返回一个null值,这时我们再借助?:操作符让它返回0。

9.2 let

let可以使自己调用自己,可以代替那种大大的if

fun doStudy2(study: Study?) {
    study?.let {
        it.doHomework()
        it.readBooks()
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值