栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Kotlin学习笔记之基础篇一

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Kotlin学习笔记之基础篇一

Kotlin学习笔记之基础篇一
  • 1.1 程序的逻辑控制
    • if条件语句
    • when条件语句
    • while循环
    • for-in循环
  • 1.2 面向对象编程
    • 继承
    • 类的主构造函数
    • 接口
    • 数据类与单例类
  • 1.3 Lambda编程
    • 集合的创建与遍历
    • 可变集合
    • Set集合和List集合的区别
    • 创建Map集合
    • 集合的函数式API
    • Java函数式API的使用
  • 1.4 空指针检查
  • 1.5 kotlin中的小魔术
    • 函数的参数默认值
    • 通过键值对的方式来传参
1.1 程序的逻辑控制 1.1.1 if条件语句

Kotlin中的if语句相比于Java有一个额外的功能,它是可以有返回值的,返回值就是if语句每一个条件中最后一行代码的返回值

// 简化前
fun largerNumber(num1: Int, num2: Int): Int {
    var value = 0
    if (num1 > num2) {
        value = num1
    } else {
        value = num2
    }
    return value
}
// 简化后
fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) num1 else num2
1.1.2 when条件语句

when语句和if语句一样,也是可以有返回值的

精确匹配

fun getScore(name: String) = when (name) {
    "Tom" -> 86
    "Jim" -> 77
    "Jack" -> 95
    "Lily" -> 100
    else -> 0
}

类型匹配

以下代码中,is关键字就是类型匹配的核心,它相当于Java中的instanceof关键字。Number类型的参数,这是Kotlin内置的一个抽象类,像Int、Long、Float、Double等与数字相关的类都是它的子类,所以这里就可以使用类型匹配来判断传入的参数到底属于什么类型。

fun checkNumber(num: Number) {
    when (num) {
        is Int -> println("number is Int")
        is Double -> println("number is Double")
        else -> println("number not support")
    }
}

不带参数的用法

这种用法是将判断的表达式完整地写在when的结构体当中

fun getScore(name: String) = when {
    name.startsWith("Tom") -> 86
    name == "Jim" -> 77
    name == "Jack" -> 95
    name == "Lily" -> 100
    else -> 0
}
1.1.3 while循环

while循环不管是在语法还是使用技巧上都和Java中的while循环没有任何区别

fun main(args: Array){
    var i = 1
    while (i<=5){
        println(i)
        i++
    }
}
1.1.4 for-in循环
val range = 0..10

上述代码表示创建了一个0到10的区间,并且两端都是闭区间。[0,10]

for (i in 0..10) {
    println(i)
}

通过for-in循环来遍历这个区间

val range = 0 until 10

用until关键字来创建一个左闭右开的区间。[0,10)

for (i in 0 until 10 step 2) {
    println(i)
}

for-in循环每次执行循环时会在区间范围内递增1,相当于Java for-i循环中i++的效果,而如果你想跳过其中的一些元素,可以使用step关键字

for (i in 10 downTo 1 step 2) {
    println(i)
}

…和until关键字都要求区间的左端必须小于等于区间的右端,也就是这两种关键字创建的都是一个升序的区间。如果你想创建一个降序的区间,可以使用downTo关键字。[10,1]

1.1.5 Kotlin中判断字符串或对象是否相等

可以直接使用==关键字,而不用像Java那样调用equals()方法。

1.2 面向对象编程 1.2.1 继承

open关键字表示类被允许继承

open class Person{
    
}

在Java中继承的关键字是extends,而在Kotlin中变成了一个冒号

class Student: Person() {

}
1.2.2 类的主构造函数

主构造函数

主构造函数将会是你最常用的构造函数,每个类默认都会有一个不带参数的主构造函数,当然你也可以显式地给它指明参数。主构造函数的特点是没有函数体,直接定义在类名的后面即可。由于构造函数中的参数是在创建实例的时候传入的,不像之前的写法那样还得重新赋值,因此我们可以将参数全部声明成val。

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

}

init结构体

主构造函数没有函数体,如果我想在主构造函数中编写一些逻辑,该怎么办呢?Kotlin给我们提供了一个init结构体,所有主构造函数中的逻辑都可以写在里面

class Student(val sno: String, val grade: Int) : Person() {
    init {
        println("sno is " + sno)
        println("grade is " + grade)
    }
}

继承时主构造参数如何传

我们在Student类的主构造函数中增加name和age这两个字段时,不能再将它们声明成val,因为在主构造函数中声明成val或者var的参数将自动成为该类的字段,这就会导致和父类中同名的name和age字段造成冲突。因此,这里的name和age参数前面我们不用加任何关键字,让它的作用域仅限定在主构造函数当中即可。

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

次构造函数

使用关键字constructor声明;kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)

open class B(val name: String, val age: Int) {}

class A(val sno: String, val grade: Int, name: String, age: Int) : B(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) {
    }
}
1.2.3 接口
interface Study {
    fun readBooks()
    fun doHomework()
}

open class Person(val name: String, val age: Int) {

}

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

    override fun doHomework() {
        println("$name is doing homework.")
    }

}

kotin允许对接口中定义的函数进行默认实现

interface Study {
    fun readBooks()
    fun doHomework() {
        println("do homework default implementation.")
    }
}

Java和Kotlin函数可见性修饰符对照表

修饰符JavaKotlin
public所有类可见所有类可见(默认)
private当前类可见当前类可见
protected当前类、子类、同一包路径下的类可见当前类、子类可见
default同一包路径下的类可见(默认)无
internal无同一模块中的类可见
1.2.4 数据类与单例类

数据类

当在一个类前面声明了data关键字时,就表明你希望这个类是一个数据类,Kotlin会根据主构造函数中的参数帮你将equals()、hashCode()、toString()等固定且无实际逻辑意义的方法自动生成,从而大大减少了开发的工作量

data class Cellphone(val brand: String, val price: Double)

单例类

在Kotlin中创建一个单例类的方式极其简单,只需要将class关键字改成object关键字即可。

object Singleton {
    fun singletonTest() {
        println("singletonTest is called.")
    }
}
1.3 Lambda编程 1.3.1 集合的创建与遍历
// 类似java写法
val list = ArrayList()
list.add("Apple")
list.add("Banana")

// kotlin写法
val list1 = listOf("Apple", "Banana")

// 使用for in 循环打印
for (str in list1) print(str)
1.3.2 可变集合

使用listOf创建的是不可变集合,使用mutableListOf创建的才是可变集合

val list1 = mutableListOf("Apple", "Banana")
list1.add("Orange")
for (str in list1) print(str)
1.3.3 Set集合和List集合的区别

Set集合中是不可以存放重复元素的,如果存放了多个相同的元素,只会保留其中一份,这是和List集合最大的不同之处。

// 不可变
var set = setOf("1","1","2")
for (str in set) print(str)

// 可变
val set1 = mutableSetOf("1","2")
set1.add("3")
for (str in set1) print(str)
1.3.4 创建map集合
// 创建可变map集合
val map = mutableMapOf("Apple" to 1, "Banana" to 2)
map["Orange"] = 3
// for in 循环打印map集合
for ((name, number) in map) print("$name is $number")
1.3.5 集合的函数式API

Lambda表达式的语法结构

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

首先最外层是一对大括号,如果有参数传入到
Lambda表达式中的话,我们还需要声明参数列表,参数列表的结尾使用一个->符号,表示参
数列表的结束以及函数体的开始,函数体中可以编写任意行代码(虽然不建议编写太长的代
码),并且最后一行代码会自动作为Lambda表达式的返回值。

Lambda的定义,如果用最直白的语言来阐述的话,Lambda就是一小段可以作为参数传递的代码。

常用的函数式API—maxBy函数

maxBy函数的工作原理是根据我们传入的条件来遍历集合,从而找到该条件下的最大值

val list = listOf("Apple", "Banana")
// 简化前
val lambda = { result: String -> result.length }
val maxLength = list.maxByOrNull(lambda)
// 简化后
val maxLength = list.maxByOrNull { it.length }

常用的函数式API—filter函数,map函数

map函数是最常用的一种函数式API,它用于将集合中的每个元素都映射成一个另外的值,映射的规则在Lambda表达式中指定,最终生成一个新的集合。

filter函数是用来过滤集合中的数据的,它可以单独使用,也可以配合刚才的map函数一起使用。

val list = listOf("Apple", "Banana")
val newList = list.filter { it.length > 2 }.map { it.length }
for (str in newList) print(str)

常用的函数式API—any和all函数

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

val list = listOf("Apple", "Banana")
val anyList = list.any { it.length > 2 }
val allList = list.all { it.length > 2 }
1.3.6 Java函数式API的使用

Kotlin中匿名类的写法

Kotlin中匿名类的写法和Java有一点区别,由于Kotlin完全舍弃了new关键字,因此创建匿名类实例的时候就不能再使用new了,而是改用了object关键字。这种写法虽然算不上复杂,但是相比于Java的匿名类写法,并没有什么简化之处.

Thread(object : Runnable {
    override fun run() {
    }
}).start()

Java函数式API的使用

Kotlin中调用Java方法时也可以使用函数式API,只不过这是有一定条件限制的。具体来讲,如果我们在Kotlin代码中调用了一个Java方法,并且该方法接收一个Java单抽象方法接口参数,就可以使用函数式API。Java单抽象方法接口指的是接口中只有一个待实现方法,如果接口中有多个待实现方法,则无法使用函数式API。

Thread { print("thread") }.start()
1.4 空指针检查

Kotlin将空指针异常的检查提前到了编译时期,如果我们的程序存在空指针异常的风险,那么在编译的时候会直接报错,修正之后才能成功运行,这样就可以保证程序在运行时期不会出现空指针异常了。

可为空的类型系统 Int? String?

很简单,就是在类名的后面加上一个问号。比如,Int表
示不可为空的整型,而Int?就表示可为空的整型;String表示不可为空的字符串,而String?就表示可为空的字符串。

判空辅助工具 ?.操作符

首先学习最常用的?.操作符。这个操作符的作用非常好理解,就是当对象不为空时正常调用相应的方法,当对象为空时则什么都不做。

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

?:操作符

?:操作符。这个操作符的左右两边都接收一个表达式,
如果左边表达式的结果不为空就返回左边表达式的结果,否则就返回右边表达式的结果。

val a = 0
val b = 0
var c = if (a != null) {
    a
} else {
    b
}
// 使用?:操作符简化代码
c = a ?: b

将?.和?:操作符结合到了一起使用

// 简化前
fun getTextLength1(text: String?): Int {
    if (text != null) {
        return text.length
    }
    return 0
}

// 使用?.和 ?:简化
fun getTextLength2(text: String?) = text?.length ?: 0

非空断言工具 !!

确信的对象不会为空,所以不用你来帮我做空指针检查了,强行通过编译,可以使用非空断言工具,写法是在对象的后面加上!!

var content: String? = "hello"
fun printUpperCase() {
    val upperCase = content!!.toUpperCase()
    println(upperCase)
}

辅助工具—let函数

obj.let { obj2 ->
    // 编写具体的业务逻辑
}
fun printUpperCase() {
    val content: String? = "hello"
    val upperCase = content?.let {
        it.toUpperCase()
        it.length
    }
    println(upperCase)
}
1.5 kotlin中的小魔术

函数的参数默认值

定义函数的时候给任意参数设定一个默认值,这样当调用此函数时就不会强制要求调用方为此参数传值,在没有传值的情况下会自动使用参数的默认值。

fun printParams(num: Int, str: String = "hello") {
    println("num is $num , str is $str")
}

通过键值对的方式来传参

printParams(str = "world", num = 123)

fun printParams(num: Int = 100, str: String) {
    println("num is $num , str is $str")
}

fun main() {
    printParams(str = "world")
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993192.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号