1 变量声明
Kotlin 使用两个不同的关键字(即 val 和 var)来声明变量。
- val 用于值从不更改的变量。使用 val 声明的变量无法重新赋值。
- var 用于值可以更改的变量。
var a:Int=10
val b:Int=10
null安全
在Kotlin直接给变量赋值null会报错,。可以在变量类型后面加上 ? 后缀,将变量指定为可为 null:
var languageName: String? = null
2 函数
2.1 函数声明
声明函数使用fun关键字
fun plusNumber(num1: Int, num2: Int): Int {
return num1+num2
}
2.2 简化函数
使用赋值运算符替换return
fun plusNumber(num1: Int, num2: Int): Int = num1+num2
2.3 匿名函数
val plusNumber3: (Int,Int) -> Int = { num1,num2 ->
num1+num2
}
2.4 高阶函数
一个函数将另一个函数作为参数,如下,定义一个高阶函数:
fun printResult(num1: Int, num2: Int, plus: (Int, Int) -> Int) {
val result = plus(num1, num2)
println("result输出结果为:$result")
}
调用高阶函数:
printResult(2, 3) { num1, num2 ->
num1+ num2
}
2.4 参数默认值
Kotlin可以给函数的参数设置默认值,这样当调用此函数时就不会强制要求给此参数传值,在没有传值的情况下会自动使用参数的默认值。
fun method(num: Int, str: String = "hello") {
println("num is $num , str is $str")
}
method(666)
3 程序控制逻辑
3.1 if条件语句
基本使用和java中一样,区别是Kotlin中的if语句可以有返回值。
fun largerNumber(num1: Int, num2: Int): Int {
var value = if (num1 > num2) {
num1
} else {
num2
}
return value
}
可简化为:
fun largerNumber(num1: Int, num2: Int): Int {
return if (num1 > num2) {
num1
} else {
num2
}
}
当一个函数只有一行代码时,可以省略函数体部分
fun largerNumber(num1: Int, num2: Int): Int = if (num1 > num2) {
num1
} else {
num2
}
进一步简化为:
fun largerNumber(num1: Int, num2: Int): Int = if (num1 > num2) num1 else num2
3.2 when条件语句
when表达式中每个分支由一个条件、一个箭头(->)和一个结果表示。
Kotlin中的When语句类似于Java中switch语句,但它比switch强大的多,When语句允许传入任意类型的参数。
when (condition) {
condition1-> { 执行逻辑 }
condition2 -> { 执行逻辑 }
else -> { 执行逻辑 }
}
示例如下:
fun checkScore(name: String) {
when (name) {
"Tom" -> {print("Tom")}
"Jack" -> print("Jack")
"Lucy" -> print("Jack")
else -> print("no")
}
}
类型匹配
fun checkNumber(num: Number) {
when (num) {
is Int -> println("number is Int")
is Double -> println("number is Double")
else -> println("number not support")
}
}
表达式匹配,例如“==”和startsWith
fun getScore(name: String) = when {
name.startsWith("Tom") -> 86
name == "Jim" -> 77
name == "Jack" -> 95
name == "Lily" -> 100
else -> 0
}
3.3 for循环
类似于java中的for-in循环
0..10//表示[0,10]
0 until 10//表示[0,10)
10 downTo 1//表示10到1
输出1到10
for (i in 0..10) {
println(i)
}
使用step关键字可以跳过一些元素 输出0,2,4,6,8
for (i in 0 until 10 step 2) {
println(i)
}
使用downTo 输出10到1
for (i in 10 downTo 1) {
println(i)
}
3.4 while循环
while循环和java基本一样
4 面向对象编程
4.1 类与对象
创建一个类
class Person {
var name = ""
var age = 0
fun eat() {
println(name + "is eating,his is " + age + " years old")
}
}
kotlin中实例化类的方式和java基本一样,只需要去掉关键字new就可以了,默认是无参构造:
var person = Person()
person.name = "jacky"
person.age = 18
person.eat()
定义一个自定义构造函数,用来指定如何初始化类属性:
open class Person(var name:String,var age:Int) {
fun eat() {
println("$name is eating,he is $age years old")
}
}
匿名内部类
创建匿名类实例的时候使用object关键字
Thread(object : Runnable {
override fun run() {
TODO("Not yet implemented")
}
})
可以简化为:
Thread { TODO("Not yet implemented") }
4.2 继承与构造函数
在Kotlin中任何一个非抽象类默认都是不可以被继承的,相当于Java中给类声明了final关键字,需要加上关键字open使Person类可以被继承
open class Person {
...
}
class Student(val sno: String, val grade: Int) : Person() {
// 可以实现类似于java构造器函数方法
init {
println("sno is:$sno")
}
}
Kotlin将构造函数分成两种:主构函数和次构函数。
主构函数
每个类默认都有一个不带参数的主构造函数,特点是没有函数体,直接定义在类名后面即可。
class Student(val sno: String, val grade: Int) : Person() {
}
次构函数
任何一个类只能有一个主构函数,但是可以有多个次构函数,有函数体。
Kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)
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) {
}
}
4.3 接口
Kotlin中允许接口中的方法有默认实现
interface Study {
fun readBooks()
fun domeHomework() {
println("domeHomework")
}
}
Kotlin中继承类和实现接口使用的都是冒号,中间使用逗号隔开
class Student : Person(), Study {
override fun readBooks() {
println("readBooks")
}
override fun domeHomework() {
println("Student domeHomework")
}
}
4.4 数据类与单例类
数据类
在一个类前面声明data关键字,表示这是一个数据类
// 定义数据类
data class Cellphone(val brand: String, val price: Double)
val cellphone1 = Cellphone("huawei", 1.68)
val cellphone2 = Cellphone("huawei", 1.68)
println("cellphone1 equals cellphone:" + (cellphone1 == cellphone2))
输出结果为true,如果不加data关键字输出结果则为false
单例类
创建一个单例类,只需要将class关键字改为object即可:
object SingletonDemo {
fun singleTest() {
println("singleTest is called")
}
}
调用单例类里面方法:
SingletonDemo.singleTest()
5 Lamba编程
5.1 集合的创建与便利
List
创建List集合的方式和Java一样:
val list = ArrayList<String>()
list.add("A")
list.add("B")
list.add("C")
list.add("D")
// 遍历集合
for (element in list) {
println(element)
}
使用listOf简化集合创建:
val list= listOf("A","B","C","D")
需要注意的是使用listOf()创建的集合是不可变的,无法对集合进行添加、修改和删除操作,使用mutableListOf()可以创建可变集合。
使用mutableListOf()创建可变集合:
val list = mutableListOf("A", "B", "C", "D")
list.add("E")
Set
Set集合的创建和便利和List集合一样,可以使用setOf和mutableSetOf进行创建:
val set1 = setOf("A", "B", "C", "D")
val set2= mutableSetOf("A", "B", "C", "D")
不同的是Set集合中的元素是不可重复的。
Map
和Java一样创建Map集合
val hashMap = HashMap<String, Int>()
hashMap.put("A", 1)
hashMap.put("B", 2)
hashMap.put("C", 3)
但是 Kotlin中不建议使用put()和get()来添加和获取数据,推荐使用如下方式:
val hashMap = HashMap<String, Int>()
hashMap["A"] = 1
hashMap["B"] = 2
hashMap["C"] = 3
hashMap["A"] = 1 // 添加数据
val a = hashMap["A"] // 获取数据
同List和Set一样,简化Map创建也可以使用mapOf和mutableMapOf:
val hashMap = mapOf("A" to 1, "B" to 2, "C" to 3)
for ((letter, num) in hashMap) {
println("letter is $letter,num is $num")
}
5.2 集合的函数式API
Lamada就是一小段可以作为参数传递的代码,表达式的语法结构为:
{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
maxBy
maxBy根据传入的条件(Lambda表达式)来遍历集合,从而找到该条件下的最大值,例如:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val lambda = { fruit: String -> fruit.length }
val maxLengthFruit = list.maxBy(lambda)
// 输出结果为Watermelon
println("max length fruit is " + maxLengthFruit)
直接将Lambda表达式传入maxBy函数中:
val maxLengthFruit = list.maxBy({ fruit: String -> fruit.length })
Kotlin规定,当Lambda参数是函数的最后一个参数时,可以将Lambda表达式移到函数括号的外面:
val maxLengthFruit = list.maxBy() { fruit: String -> fruit.length }
如果Lambda参数是函数的唯一一个参数的话,还可以将函数的括号省略:
val maxLengthFruit = list.maxBy{ fruit: String -> fruit.length }
当Lambda表达式的参数列表中只有一个参数时,也不必声明参数名,而是可以使用it关键字来代替,那么代码就变成了:
val maxLengthFruit = list.maxBy { it.length }
map
map函数用于将集合中的每个元素都映射成一个另外的值,映射的规则在Lambda表达式中指定,最终生成一个新的集合
val newList = list.map { it.toUpperCase() }
filter
filter函数用来过滤集合中的数据。
val newList = list.filter { it.length <= 5 }
.map { it.toUpperCase() }
any
any函数用于判断集合中是否至少存在一个元素满足指定条件
val anyResult = list.any { it.length <= 5 }
all
all函数用于判断集合中是否所有元素都满足指定条件
val allResult = list.all { it.length <= 5 }
6 空指针检查
可空类型系统
在类型的后面加“?”。例如Int?就表示可为空的整型,Student?表示stu可为空。
fun doStudy(stu: Student?) {
stu.readBooks()
}
fun main() {
doStudy(null)
}
判空辅助工具
“?.”操作符:表示当对象不为空时调用
a?.doSomething()
"?:"操作符:如果左边的表达式不为空则返回左边结果,否则返回右边结果。
val c = a ?: b
7、内嵌表达式
内嵌基本数据类型使用“$”
var a:Int=4
var b:String="abc"
fun main() {
println("a is $a,b is $b")
}
内嵌对象中的值使用“${ }”
println("hello, ${stu.name}. nice to meet you!")