变量和函数
变量
- val 不可变变量,无法再次赋值
- var 可变变量
- 强制类型转换:变量 as 类型
//主函数
fun main() {
//自动推导成整型变量
var a = 10
//显式声明变量类型
//kotlin中没有基本数据类型,全部使用对象数据类型,首字母大写
var b: Int
//延迟初始化
lateinit var c :Int
//判断是否初始化
if(!::c.isInitialized){
c=100
}
}
集合
fun main() {
//不可变数组
val list = listOf("Apple","banana","orange","pear")
//可变数组
val mutlist = mutableListOf("Apple","banana","orange","pear")
mutlist.add("watermelon")
//集合,map同理
val set = setOf("Apple", "banana", "orange", "pear")
val mutableSet = mutableSetOf("Apple", "banana", "orange", "pear")
val mapOf = mapOf("apple" to 1, "banana" to 2)
//map
val map = HashMap<String, Int>()
//相当于put
map["Apple"] = 1
map["orange"] = 2
//相当于get
val number = map["Apple"]
}
函数
fun+函数名+(变量:变量类型,......)+:返回类型+{}
fun largerNumber(a: Int, b: Int): Int {
return max(a, b)
}
//当函数只有一行代码时不用写函数体,用等号连接代码
fun largerNumber2(a: Int, b: Int): Int = max(a, b)
//返回值类型可自动推断
fun largerNumber3(a: Int, b: Int) = max(a, b)
//函数参数默认值(类似python)
fun printParams(num : Int = 100,str :String){
println("number is $num,str is $str")
}
//使用时可以使用键值对
fun main() {
printParams(num = 10,str = "zhaolu")
//输出number is 10,str is zhaolu
}
静态方法(类方法)
使用companion object实现近似静态方法
class FuncDemo {
companion object{
fun doAction(){
print("do action")
}
}
}
fun main() {
FuncDemo.doAction()
//输出do action
}
也可以使用顶层方法
创建一个Helper kotlin file,里面写方法,其他类可以直接使用此函数
//Helper
fun doSomething(){
println("do something")
}
//其他类
fun main() {
doSomething()
//输出do something
}
逻辑控制
if
/*
* if语句使用方法同java
* if可以有返回值
* */
fun largerNumber(a: Int, b: Int) = if (a > b) a else b
when
/*
* when相当于switch
* 匹配值 -> 执行语句
* */
fun getScore(name: String) = when (name) {
"Tom" -> 100
"Jack" -> 95
"Lily" -> 80
else -> 0
}
//可判断数据类型,用Int
fun checkNumber(num :Number) {
when (num){
is Int -> print("number is Int")
is Double -> print("number is Double")
else -> print("don't know")
}
}
while
同java
for
类似python
//定义区间,闭区间
val range = 1..5
for (i in range){
print(i);
}
println(" ")
//左闭右开
val range2 = 0 until 5
for (i in range2) {
print(i)
}
println(" ")
//设置步长
for(i in 0 until 10 step 2){
print(i)
}
println(" ")
//降序
for(i in 10 downTo 1){
print(i)
}
面向对象
类与对象
类的定义与继承
//加open关键字才可以继承,默认不可以继承
open class Person{
var name =""
var age = 0
fun eat(){
println(name+"is eating"+",his age is "+age)
}
}
//继承使用:clsaasName(),子类的构造函数必须调用父类的构造函数
class Student : Person(){
var sno = ""
var grade = 0
}
//类名后加主构造函数
//init块中可以写主构造函数逻辑
class Student2(val sno :String,val grade:Int):Person(){
init {
println("Sno is"+sno)
println("Grade is"+grade)
}
}
open class Person2(val name:String ,val age:Int){
fun eat(){
println(name+"is eating"+",his age is "+age)
}
}
//class Student3(val sno :String,val grade:Int):Person2(){} //No value passed for parameter 'age'
//继承有主构造函数的父类
class Student3(val sno :String,val grade:Int,name: String,age: Int):Person2(name,age){
//次构造函数
constructor(name: String,age: Int):this("",0,name,age){}
constructor():this("",0)
}
类实例的创建
fun main() {
//创建对象省略new
var p = Person()
//kotlin中去掉了get,set方法,直接使用 .属性名 赋值
p.name = "Tom"
p.age = 10
p.eat()
val s1 = Student2("01921210001",100)
}
接口
定义
interface Study {
fun readBook()
//接口方法默认实现
fun doHomeWork(){
println("doHomework default implementation")
}
}
使用接口
//继承实现统一使用冒号,用逗号分隔
class StuInterface(name: String, age: Int) : Person2(name, age), Study {
override fun readBook() {
println("read book")
}
}
fun main() {
val s = StuInterface("tom", 20)
s.doHomeWork()
s.readBook()
}
修饰符
- public:默认,所有类可见
- private:同java,只对当前类可见
- protected:只在当前类和子类使用(与java不同)
- internal:只对同一模块的类可见
数据类
//数据类自动生成equals(),hashcode(),tostring()方法
data class CellPhone(val brand:String,val price:Int)
单例类
//单例类,使用object
object Singleton {
fun singletonTest(){
println("singletonTest is called")
}
}
fun main() {
Singleton.singletonTest()
}
密封类
当when传入一个密封类,会自动检查该密封类的子类,强制要求处理每个子类
sealed class Result
class Success(val msg:String):Result()
class Failure(val error:Exception):Result()
Lambda编程
- 形式:{参数1:类型,参数2:类型 -> 函数体}
- 当lambda参数是函数最后一个参数可以拿到外边
- 当lambda参数是唯一参数括号可以不写
- 当参数列表只有一个可以用it代替,不用声明参数名
fun main() {
val list = listOf("Apple","banana","orange","pear")
//原始写法,maxByOrNull根据传入的条件遍历,找到最大值
val lambda = { fruit: String -> fruit.length }
val maxLen = list.maxByOrNull(lambda)
//省略写法
println("max is "+list.maxByOrNull { it.length })
//map把集合中的函数映射成为另一个值
val map = list.map { it.toUpperCase() }
for (s in map) {
println(s)
}
//flilter过滤
val filter = list.filter { it.length <= 5 }
for (s in filter) {
println(s)
}
val any = list.any { it.length <= 5 }
val all = list.all { it.length <= 5 }
println("any is "+any)
println("all is "+all)
Thread{ print("thread is start")}.start()
}
空指针检查
//变量不许为空,如果需要为空,在后面加?
class Study {
fun readBook(){
println("read book")
}
fun doHomework(){
println("do homework")
}
}
fun doStudy(study: Study){
study.doHomework()
study.readBook()
}
//变量不许为空,如果需要为空,在后面加?
fun doStudy2(study: Study?){
study?.doHomework()
study?.readBook()
}
fun main() {
//Null can not be a value of a non-null type Study
// doStudy(null)
doStudy2(null)
}
val c = if(a!=null){
a
}else {
b
}
//可以简化为
val c = a ?: b
//非空断言语句,在变量后加!!,不推荐
let函数
obj调用let函数,立即执行lambda表达式代码,同时将obj传递到表达式中,即obj2
obj.let{obj2->
//执行语句
}
//作为空指针判断辅助工具
fun doStudy3(study: Study?){
study?.let { stu ->
stu.doHomework()
stu.readBook()
}
}
fun doStudy4(study: Study?){
study?.let {
it.readBook()
it.doHomework()
}
}
其他技巧
字符串内嵌表达式
//使用${obj.name}
fun main() {
val brand = "xiaoMi"
val price = 1999
println("$brand's price is $price")
//输出xiaoMi's price is 1999
}
with函数
两个参数,第一个参数为任意类型的对象,第二个参数为lambda表达式,在lambda表达式中提供第一个参数对应的上下文,并使用最后一行代码作为返回值
fun main() {
val list = listOf("apple","banana")
val res = with(StringBuilder()){
for (s in list) {
append(s)
append("\n")
}
//返回值
toString()
}
println(res)
}
run函数
类似with
fun main() {
val list = listOf("apple","banana")
//只有此处有区别
val res = StringBuilder().run {
for (s in list) {
append(s)
append("\n")
}
toString()
}
println(res)
}
apply函数
类似run,区别在于无返回值,返回调用对象本身
fun main() {
val list = listOf("apple","banana")
//res为StringBuilder类型
val res = StringBuilder().run {
for (s in list) {
append(s)
append("\n")
}
}
//需要加toString()
println(res.toString())
}
repeat函数
//将lambda表达式执行n遍
repeat(n){
//lambda表达式
}