Hello World
fun main() {
println("Hello World")
}
每一行代码无需加分号。
变量和函数
变量
val 不可变变量
var 可变变量
// 写法一:类型推倒机制
fun main(){
val a = 10
println("a = "+ a)
}
// 写法二:显示声明变量类型
fun main(){
val a :Int = 10
println("a = "+ a)
}
优先使用val
声明变量,当无法满足时再使用var
,这样程序会更健壮,更规范。
函数
// 无参,无返回值
fun methodName(){
}
// 有参,无返回值
fun methodName(param1: Int,param2: Int){
}
// 有参,有返回值
fun demo(param1: Int,param2: Int): Int{
return a + b
}
demo:
fun main() {
val a = 10
val b = 2
val value = sumNum(a, b)
println(value)
}
fun sumNum(a: Int, b: Int): Int {
return a + b
}
Kotlin 语法糖,不写函数体和return。
fun main(){
val a = 10
val b = 2
val value = sumNum(a,b)
println(value)
}
fun sumNum(a:Int,b:Int):Int = a + b
// 简写
fun sumNum(a:Int,b:Int) = a + b
程序逻辑控制
if 条件语句
fun main() {
val a = 10
val b = 2
val value = maxNum(a, b)
println(value)
}
// 1、一般写法
fun maxNum(a: Int, b: Int): Int {
var value = 0
if (a > b) {
value = a
} else {
value = b
}
return value
}
// 2、精简写法
fun maxNum(a: Int, b: Int): Int = if (a > b) a else b
when 条件语句
类似 java 的 switch,强于 switch。
fun main() {
val a = "a"
val value = getScore(a)
println(value)
}
fun getScore(name: String) = when (name) {
"a" -> 86
"b" -> 26
"c" -> 36
"d" -> 31
else -> 0
}
可传入任意类型参数。格式:匹配值 -> { 执行逻辑 }
。当执行逻辑为一行代码时,{}
可省略。is
关键字时类型匹配的核心。
fun main() {
val a = 1
checkNum(a)
}
fun checkNum(num: Number) {
when (num) {
is Int -> println("Int")
is Double -> println("Double")
else -> println("other")
}
}
当 when 中不传入参数,可以这么写:
fun main() {
val a = "a"
val value = getScore(a)
println(value)
}
fun getScore(name: String) = when {
name == "a" -> 86
name == "b" -> 26
name == "c" -> 36
name == "d" -> 31
else -> 0
}
Kotlin 中判断字符串或对象是否相等可以直接使用 ==
。
fun main() {
val a = "ade"
val value = getScore(a)
println(value)
}
fun getScore(name: String) = when{
name.startsWith("a") -> 86
name == "b" -> 26
name == "c" -> 36
name == "d" -> 31
else -> 0
}
字符a
开头的分数都是 86。
循环语句
for 循环,..
创建两端闭区间的关键字,0..10
相当于[0,10]
。
fun main() {
for(i in 0..10){
println(i)
}
}
左闭右开区间,使用until
关键字。
// [0,10)
val range = 0 until 10
step
关键字,step 2
相当于i = i + 2
,每次循环递增2。
fun main() {
for(i in 0 until 10 step 2){
println(i)
}
}
降序区间使用关键字downTo
,如创建一个[10,1]
的降序区间。
fun main() {
for(i in 10 downTo 1){
println(i)
}
}
面向对象编程
类和对象
fun main() {
val p = Person()
p.name = "oo"
p.age = 10
p.eat()
}
class Person {
var name = ""
var age = 0
fun eat() {
println(name + " eat " + " age:" + age)
}
}
继承与构造函数
如果一个类需要被继承,那么得在类名前加上关键字open
。子类继承父类,需要关键字 :
fun main() {
val p = Student()
p.name = "oo"
p.age = 10
p.eat()
}
// 父类
open class Person {
var name = ""
var age = 0
fun eat() {
println(name + " eat " + " age:" + age)
}
}
// 子类,注意父类需要加上 ()
class Student:Person() {
var sno = ""
var grade = 0
}
构造函数分为两种:主构造函数、次构造函数。任何类只能有一个主构造函数,可有多个次构造函数。
fun main() {
val p = Student("01",89)
p.name = "oo"
p.age = 10
p.eat()
println(p.sno+" "+p.grade)
}
open class Person {
var name = ""
var age = 0
fun eat() {
println(name + " eat " + " age:" + age)
}
}
// 主构造函数 父类()为无参构造函数
class Student(val sno:String,val grade:Int):Person() {
}
fun main() {
val p = Student("01",89,"lisi",12)
p.eat()
println(p.sno+" "+p.grade)
}
open class Person (val name:String,val age:Int){
fun eat() {
println(name + " eat " + " age:" + age)
}
}
// 主构造函数 父类()为有参构造函数,子类不需要声明 val
class Student(val sno:String,val grade:Int,name:String,age:Int):Person(name,age) {
}
当一个类有主次构造函数时,所有次构造函数必须调用主构造函数(包括间接调用),通过this
关键字调用主构造函数。
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){
}
}
接口
interface Study {
fun readBook()
fun doHomeWork(){
// 如未实现则默认实现
}
}
class Student(name: String, age: Int) : Person(name, age), Study {
override fun readBook() {
println("$name is reading")
}
override fun doHomeWork() {
println("$name is doing homework")
}
}
可见修饰符
public(默认)、private(当前类内部可见)、protecte(当前类子类可见)、internal(同一模块中可见)
数据类和单例类
数据类,只需要data
关键字,会将equals()
、hashCode()
、toString()
等方法自动生成。
data class Cellphone(val brand: String, val price: Double)
单例类,使用关键字object
。
object Singleton {
fun singletonTest(){
//
}
}
调用方式:Singleton.singletonTest()
Lambda编程
集合的创建和遍历
List
fun main(){
// 初始化集合 listOf->不可变集合
val list = listOf("a","b","c","d")
for(s in list){
println(s)
}
}
// 初始化集合 mutableListOf->可变集合
val mutableList = mutableListOf("a","b","c","d")
mutableList.add("e")
for(s in mutableList){
println(s)
}
Set
fun main(){
// 不可变,无序
val set = setOf("a","b","c","d")
for(s in set){
println(s)
}
// 可变,无序
val mutableSet = mutableSetOf("a","b","c","d")
mutableSet.add("g")
for(s in mutableSet){
println(s)
}
}
Map
fun main() {
// 不可变
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
for ((k, v) in map) {
println("key:$k-value:$v")
}
// 可变
val mutableMap = mutableMapOf("a" to 1, "b" to 2, "c" to 3)
val d = "d"
mutableMap[d] = 4
for ((k, v) in mutableMap) {
println("key:$k-value:$v")
}
}
集合的函数式API
Lambda表达式:
{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
fun main(){
val list = listOf("this","share","and")
// val maxLen = list.maxByOrNull({word:String->word.length})
// val maxLen = list.maxByOrNull() {word:String->word.length}
// val maxLen = list.maxByOrNull{word:String->word.length}
// val maxLen = list.maxByOrNull{word->word.length}
val maxLen = list.maxByOrNull{it.length}
println(maxLen)
}
map
集合中map
函数,将集合中每个元素映射成一个另外的值,映射规则在lambda
表达式指定,最终生成一个新的集合。
fun main(){
val list = listOf("this","share","and")
val newList = list.map{it.toUpperCase()}
for(s in newList){
println(s)
}
}
filter
集合中filter
函数,过滤集合中数据。
fun main() {
val list = listOf("this", "share", "and")
val newList = list.filter { it.length < 4 }.map { it.toUpperCase() }
for (s in newList) {
println(s)
}
}
注意:先过滤再映射
all、any、count、find
all:如果对所有元素都满足表达式,则使用all函数,返回Boolean值。
any : 如果所有元素是否至少存在一个元素匹配,则使用any函数 ,返回Boolean值。
count : 如果想知道多少个元素满足,则使用count ,返回Int值。
find : 要找到一个满足条件的元素,使用find函数 ,返回符合条件元素。
fun main(){
val list = listOf("this","share","and","yes")
val anyResult = list.any{it.length < 4}
val allResult = list.all{it.length < 4}
val countResult = list.count{it.length < 4}
val findResult = list.find{it.length < 4}
print("anyResult:$anyResult -- allResult:$allResult -- countResult:$countResult -- findResult:$findResult")
// anyResult:true -- allResult:false -- countResult:2 -- findResult:and
}
空指针检查
可空类型
fun Study(study:study?){
if(study != null){
fun readBook()
fun doHomeWork()
}
}
判空辅助工具
?.
对象不为空时调用相应方法(如果接收者非空,就调用一个方法或访问一个属性)。
if (a != null){
a.doFun()
}
// 简化写法
a?.doFun()
fun Study(study:study?){
study?.readBook()
study?.doHomeWork()
}
? :
如果 ?:
左侧表达式?空,elvis
操作符就返回其左侧表达式,否则返回右侧表达式。请注意,当且仅当左侧为空时,才会对右侧表达式求值。
val c = b?.length ?:-1
作用域函数
let
let 将对象本身作为参数传递到 Lambda 表达式中。
fun doStudy(syudy:Study?){
study?.let{stu ->
stu.readBook()
stu.doWork()
}
}
// 简化
fun doStudy(syudy:Study?){
study?.let{
it.readBook()
it.doWork()
}
}