kotlin学习笔记
和Java的区别
-
kotlin
不区分基本类型和引用类型,统一都是引用类型 -
var
: 定义变量 -
val
: 定义常量,定义后不可更改,相当于java
中的final
类型的变量 -
kotlin
不需要new
关键字创建对象 -
kotlin
中的方法可以独立存在, 方法可以嵌套 -
顶层函数: 定义在代码文件顶部的函数, 相当于
Java
中的静态工具类,代码更加简洁 -
Kotlin
相比于Java
,没有受检异常 -
获取对象的属性,不需要
getter
,setter
方法
var p=Person()
println(p.a)
- 如果一个变量只声明不赋值,需要约束变量的类型
var b //编译错误
-
字符串+数字可行,但是数字+字符串不可行
-
Byte
不能转化为Int
,不能强制转换,不是同一个继承关系 -
每一个数据类型都是一个对象,只有
Int
没有int
-
Any
是基类,相当于Object
有特色的语法
- 运算符重载:
val mutableMap = mutableMapOf<String, Int>("1" to 3)
val value = mutableMap["1"] // 等价于 mutableMap.get("1")
mutableMap["2"] = 5 // 等价于 mutableMap.put("2", 5)
闭区间 ..
语法: 值 in 起始值..结束值
半开区间 until
:
for (i in 1 until 10) print(i) // 输出:123456789
倒序区间 downTo
for (i in 10 downTo 1) print(i) // 输出:10987654321
step
按指定步长跳过元素
(1..10 step 2).forEach { println(it) } // 输出:1, 3, 5, 7, 9
高级用法:
val list = (1..5).toList() // [1, 2, 3, 4, 5]val isInRange = 5 in 1..10 // true
安全调用操作符 ?.
含义:
-
左侧非空 → 继续执行后续操作
-
左侧为空 → 返回
null
,不会抛出异常。
var a= readLine()?.toInt()
Elvis
操作符(?:
):
左侧为 null
时,返回右侧的默认值
val name = user?.name ?: "Guest" // 如果user或user.name为null,返回"Guest"
数组
数组 (array
): 不可变
// 创建包含指定元素的数组
val array1 = arrayOf(1, 2, 3) // 类型推断为Array<Int>
val array2 = arrayOf(1, true, "2") // 创建混合类型数组(Array<Any>)[1](@ref)
Kotlin
提供的数组:
val intArray1 = IntArray(5) // 长度为5的空数组
val intArray2 = IntArray(5) { 100 } // [100, 100, 100, 100, 100]
val intArray3 = IntArray(5) { it * 2 } // [0, 2, 4, 6, 8][1](@ref)
集合
List
: 有序集合,不可变, 不支持修改,没有 add
等方法
var list = listOf<Int>(1,2);
println(list.size);
mutableList
:可变集合,可以修改
mutableSet
也是可变集合,无序,不允许重复元素,无索引
var list = mutableListOf<Int>(1, 2, 3, 4);
list.add(1);
Set
:无序,元素不重复
元组
二元元组:不可变
val pair = Pair("Alice", 25) // Pair<String, Int>
val pair = "Alice" to 25 // 等价于 Pair("Alice", 25) [3,7](@ref)println(pair.first) // 输出: Alice
println(pair.second) // 输出: 25
三元元组:不可变
val triple = Triple("Alice", 25, "Engineer") // Triple<String, Int, String>println(triple.first) // 输出: Alice
println(triple.second) // 输出: 25
println(triple.third) // 输出: Engineer
to
关键字: 创建 Pair
对象
val pair = "name" to "Alice" // 创建 Pair<String, String>
val map = mapOf(1 to "one", 2 to "two") // 创建 Map<Int, String>
语句
if()
语句,可以有返回值,但是如果有返回值,必须有 else
分支, if
语句的最后一行就是返回值
val pair = Pair("Alice", 25) // Pair<String, Int> val pair1 = Pair("Alice", 26) // Pair<String, Int>
var re= if (pair.equals(pair1)) { println(pair1) 3 }else{ 4
} println(re)
when()
语句
多条件判断:
when (day) {"Saturday", "Sunday" -> println("Weekend") // 多值匹配in 1..5 -> println("Weekday") // 范围匹配else -> println("Invalid")
}
可以代替 if()
语句
var score=100;
when { score >= 90 -> println("A") score >= 80 -> println("B") else -> println("C")
}
函数
函数:
fun sum(a: Int, b: Int): Int {return a + b
}fun sum(a: Int, b: Int) = a + b
输入:
var a= readLine() //读取输入,返回字符串,可以调用方法转为 Int 等类型
数据类:
data class User(val name: String, val age: Int)
字符串模板: 不用像 java
那样拼接字符串
var name="1"
var age=1
val message = "Name: $name, Age: ${age + 1}"
println(message)
标签 name@
:
outer@ for (i in 1..3){ for (j in 1..3) { if (i==2 && j==1) break@outer//直接跳出最外层循坏 println("$i,$j") }
}
a@for (i: Int in 1..3) { // 外层循环标签 a@ for (j: Int in 1..3) { if (i == 2 && j == 2) { continue@a // 跳过外层循环的当前迭代(i=2) } println("i:$i j:$j") // 输出结果 }
}
infix
关键字将函数声明为中缀表达式
:
infix fun Int.sum(a: Int) = this + a
println(1 sum 2)
函数要满足的条件:
-
是成员函数或扩展函数
-
只能有一个参数(不能是可变参数
vararg
) -
必须用
infix
修饰
CharRange
:用于表示字符范围的类
val charRange: CharRange = 'a'..'z' // 包含 'a' 到 'z' 的所有字母
java
中的 split()
方法会将传入的参数当作正则表达式, 可以使用转义字符区别
但是 kotlin
中的不会
String str = "192.168.1.1";
String[] ips = str.split(".");
for (String ip : ips) { System.out.println(ip);
}
//控制台输出为空
lambda
表达式基本结构为 { 参数 -> 函数体 }
:
val sum = { a: Int, b: Int -> a + b }
println(sum(3, 4)) // 输出: 7
is
运算符: 判断一个类是不是另一个类的实例, 有智能类型转换,不用手动强制转换
val obj: Any = "Hello"
if (obj is String) { println(obj.length) // 自动识别为String类型
}
as
:强制转换运算符
as?
: 转换失败时返回null
, 不抛出异常
kotlin
的继承是 :
Kotlin
默认所有类为final
(不可继承),必须使用 open
关键字标记类和方法才能继承重写
open class Animal(val name: String) { // 必须声明为open才能被继承open fun makeSound() { // 必须声明为open才能被重写println("Generic sound")}
}
class Dog(name: String) : Animal(name) {override fun makeSound() { // 必须使用override关键字println("$name says: Woof!")}
}
方法重写:
父类方法使用 open
标记,子类方法使用 override
重写
子类可以对重写方法添加final
修饰,禁止进一步重写
可以用var
重写val
(反之不行)
open class Vehicle { open val speed: Int = 100 }
class Car : Vehicle() { override var speed: Int = 60 }
$
符号: 在字符串中插入变量值
val name = "Alice"
val age = 30
val message = "Name: $name, Age: $age" // 输出:Name: Alice, Age: 30
${}
符号:表达式(如运算、方法调用)用这个包裹
拓展函数: 给现有类添加新的方法,不能访问类的私有成员
语法:fun 类名.函数名()
// 给String类添加扩展函数
fun String.greet(): String {return "Hello, $this!"
}fun main() {val name = "Alice"println(name.greet()) // 输出:Hello, Alice!
}
// 给Int类添加扩展属性
val Int.isEven: Booleanget() = this % 2 == 0fun main() {println(4.isEven) // 输出:trueprintln(5.isEven) // 输出:false
}