Kotlin基本语法学习笔记

初识Kotlin

安装intellij IDEA步骤

第一个Kotlin程序

第1步 - 打开IntelliJ IDEA,选择Projects,再点New Project。

第2步 - 选择Java 选项,提供项目SDK路径并在Kotlin/JVM 框架打勾选中。

第3步 - 在新框架中提供项目详细信息(名称和存储目录),然后单击“完成”。

第4步 - 创建一个新的Kotlin文件来运行Kotlin的第一个例子。 打开:src -> New -> Kotlin File/Class。

第5步 - 输入文件名 - HelloWorld 并单击“OK”,如下图所示

第6步 - 在HelloWorld.kt文件中编写下以下代码。 Kotlin文件和类以.kt扩展名保存。

第7步 - 运行该文件

Kotlin变量

变量指的是内存位置,它用于存储数据。 变量数据可以根据条件或传递给程序的信息进行更改和重用。

变量的声明

在Kotlin中,使用关键字varval来声明变量。

Kotlin中不需要明确指定变量的类型。 Kotlin编译器通过initilizer表达式自动识别推断。

var language ="Java"
val salary = 30000
val author = "maxsu"

Kotlin可以在声明变量时明确指定变量的类型:

var language: String ="Java"
val salary: Int = 30000

Kotlin可以变量声明后执行程序时初始化。

var language: String
language = "Java"
val salary: Int
salary = 30000

注意:在变量名后面加冒号可指定变量类型。

关键字 var 和 val 的区别

var(可变变量):在程序中可更改使用var关键字声明的变量的值。

val(不可变变量):不能改变使用val关键字声明的变量的值,可简单理解为常量定义。

示例1:

var salary = 30000
salary = 40000 // 有效,可以执行

示例2:

val language = "Java"
language = "Kotlin" // 出错

Kotlin的数据类型和数组

数据类型(基本类型)是指与变量和函数关联的数据的类型和大小。数据类型用于声明确定数据特征的变量的存储位置。

在Kotlin中,一切都是对象,这意味着可以在任何变量上调用成员函数和属性。Kotlin内置数据类型分为以下几种类别:

  1. 数字
  2. 字符
  3. 字符串
  4. 布尔
  5. 数组(集合)

数字类型

数字类型是仅包含数字类型数据变量的数据类型。它又进一步分为整数和浮点数。

数据类型位宽数值范围
Byte8-128 ~ +127
Short16-32768 ~ +32767
Int32-2,147,483,648 ~ +2,147,483,647
Long64-9,223,372,036,854,775,808 ~ +9,223,372,036,854,775,807
Float321.40129846432481707e-45 ~ 3.40282346638528860e+38
Double644.94065645841246544e-324 ~ 1.79769313486231570e+308

注意:Kotlin将整数默认为Int类型,而小数默认为Double类型。对于浮点型和长整型需要分别添加后缀F和L。

val x:Float=3.1345F
val y:Double=3.45666
val z:Long = 345L

字符(Char)数据类型

使用关键字char表示字符。 char类型使用单引号(‘’)声明。

数据类型位宽数值范围
Char8-128 ~ +127
val value1 = 'A'  //利用了Kotlin数据类型的自动推断功能。
val  value2: Char
value2= 'A'

布尔数据类型

布尔数据使用Boolean类型表示。 它包含值true或false。

数据类型位宽数值范围
Boolean1true 或 false
val flag1 = true
val flag2:Boolean = true
//利用了Kotlin数据类型的自动推断功能,两种代码等价。

数据类型的转换

类型转换是将一个数据类型变量转换为另一种数据类型的过程。 在Kotlin中,不支持将较小数据类型隐式转换为较大数据类型。 例如,Int不能分别隐式转换为Long或Double,但可以显式转换(调用函数)为上述类型。

例:

var value1 = 10  // 自动推断为Int类型
val value2: Long = value1  // 编译错误,(隐式转换)类型不匹配
val value3: Long = value1.toLong() //正确,显示转换

数据类型转换函数(显式转换函数)

函数名称释义
xx.to(U)Byte()转换为(U)Byte型整数
xx.to(U)Short()转换为(U)Short型整数
xx.to(U)Int()转换为(U)Int型整数
xx.to(U)Long()转换为(U)Long型整数
xx.toFloat()转换为Float型浮点数
xx.toDouble()转换为Double型浮点数
xx.toChar()转换为Char型数据
xx.toString()转换为String型数据

在Kotlin中,不论对数据进行何种类型的转换,都建议使用显示转换函数进行操作,以避免一些莫名其妙的Bug。

数组

Kotlin中的数组由Array类表示。使用库函数arrayOf()和Array()构造函数创建数组。 Array有get(),set()函数,size属性以及一些其他有用的成员函数。

构造函数arrayOf()构造函数Array()意义
arrayOf()Array()数组
(u)byteArrayOf()ByteArray()字节型数组
(u)shortArrayOf()ShortArray()短整型数组
(u)intArrayOf()IntArray()整型数组
(u)longArrayOf()LongArray()长整型数组
booleanArrayOf()BooleanArray()布尔型数组
charArrayOf()CharArray()字符型数组
floatArrayOf()FloatArray()浮点型数组
doubleArrayOf()DoubleArray()双精度浮点型数组

使用库函数arrayOf()创建数组

arrayOf()函数创建包装类型数组。 item值在arrayOf()函数内传递,如arrayOf(1,2,3),它创建一个数组[1,2,3]。

通过索引值**array [index]**访问数组的元素。数组索引从0开始。

例:

val id = arrayOf(1,2,3,4,5)
val firstId = id[0]
val lasted = id[id.size-1]
val arr0 = doubleArrayOf(1.2, 4.5, 5.6, 9.1)
val arr1 = intArrayOf(1,2,3)
val arr2 = byteArrayOf(1,2,3,4)
val arr3 = longArrayOf(3,4,5,6,7,9)

使用Array()构造函数创建数组

使用Array()构造函数创建数组时,需要在Array()构造函数中使用两个参数:

  • 参数一作为数组的大小

  • 参数二作为函数,用于初始化并返回给定索引的数组元素的值。

例:

val asc0 = Array(5) { i -> i * 2 } // asc[0,2,4,6,8]
val asc1 = IntArray(10){i->i*i}
val asc2 = DoubleArray(50){2.5}

数组的索引

  • 获取元素

    arr0[index]
    arr0.component2()
    
  • for循环——元素遍历

    for(item in arr1) {
        println(item)
    }
    
  • for循环——下标遍历

    for(i in arr2.indices){
        println(i.toString()+"->"+arr2[i])
    }
    
  • for循环——遍历元素(带索引)

    for((index, item) in arr3.withIndex()) { //同时遍历下标和元素
        println("$index,$item")
    }
    
  • forEach遍历数组(数组对象自身的成员函数)

    asc2.forEach { println(it) }
    
  • forEach增强版(数组对象自身的成员函数)

    asc1.forEachIndexed{index,item ->println("$index:$item")}
    

字符串

Kotlin中的字符串由String类表示。字符串是不可变的,这意味着无法更改String中的元素。

字符串声明:

val text1 = "Hello Kotlin!"

**转义字符串 :**转义字符串在双引号(“”)内声明,并且可能包含转义字符,如’\n’,‘\t’,'\b’等。

val text2 = "Hello Kotlin,\n Hello Android!"

**多行字符串 :**行字符串在三引号(“”" … “”")内声明。 它提供了在新行中声明String并包含多行的工具。行字符串不能包含任何转义字符。

val text3 ="""
123
456
789
abc
def
""".trimIndent()

字符串元素

字符串中存在的字符称为字符串元素。 通过索引操作string[index]访问字符串的元素。 String的索引值从0开始,以字符串string [string.length-1]结束。 索引0表示第一个元素,索引1表示第二个元素,依此类推。

示例:

fun main(args: Array<String>) {
    val str = "Hello, yiibai!"
    println(str[0])
    println(str[1])
    println(str[str.length-1])
}
  • 字符串模板表达式是一段代码,它计算并将结果返回到字符串中。 两种字符串类型(转义和原始字符串)都包含模板表达式。

  • 字符串模板以美元符号$开头,其中包含变量名称或花括号中的任意表达式。

示例:

val str = "abcd"
println("$str 是一个字符串,它的长度是:${str.length}")

字符串的相等

在Kotlin中,字符串相等比较是在结构相等()和引用相等(=)的基础上完成的。在结构相等中,两个对象在内存中具有单独的实例但包含相同的值。引用相等指定两个不同的引用将指向同一实例内存。

结构相等(==)与不相等(!=)

要检查包含相同值的两个对象,可使用==运算符或!=运算符进行否定。

示例:

fun main(args: Array<String>) {
    val str1 = "Hello, World!"
    val str2 = "Hello, World!"
    println(str1==str2) //true
    println(str1!=str2) //false
}
//注意:结构相等(==)与不相等(!=)只比较字符串的值是否一致。
引用相等(=)与不相等(!)

要检查两个不同的引用指向同一个实例,可使用===运算符。 !==运算符用于否定。 a === b当且仅当a和b都指向同一个对象时才指定true。

若字符串相同,系统只构建一个实例,除非用StringBuilder函数构建字符串。

示例:

val str1 = "Hello, World!"
val str2 = "Hello, World!"
println(str1==str2) //true
println(str1!=str2) //false
println(str1===str2) //true
println(str1!==str2) //false
val str3 = StringBuilder("Hello, Kotlin!")
val str4 = StringBuilder("Hello, Kotlin!")
println(str3===str4) //false
println(str3!==str4) //true

字符串的属性

属性名称释义
length: Int它返回字符串序列的长度。
indices: IntRange它返回当前char序列中有效字符索引的范围。
lastIndex: Int它返回char序列中最后一个字符的索引

字符串的函数

函数名称释义
compareTo(other: String): Int它将当前对象与指定对象进行比较以获得顺序。 如果current等于指定的其他对象,则返回0。
get(index: Int): Char它返回当前字符序列中给定索引处的字符。
plus(other: Any?): String它返回连接字符串,其中包含给定其他字符串的字符串表示形式。
subSequence(startIndex: Int,endIndex: Int): CharSequence它从当前字符序列返回从startIndex开始到endIndex新的字符序列。
CharSequence.contains(other: CharSequence, ignoreCase: Boolean = false):Boolean如果字符序列包含指定的字符序列,则返回true。
CharSequence.count(): Int它返回char序列的长度。
String.drop(n: Int): String删除前n个字符后返回一个字符串。
String.dropLast(n: Int): String删除最后一个n字符后返回一个字符串。
CharSequence.elementAt(index: Int): Char它将返回给定索引处的字符,或如果索引在字符序列中不存在,则抛出IndexOutOfBoundsException。
CharSequence.indexOf(char: Char, startIndex: Int = 0, ignoreCase: Boolean = false): Int它返回从给定的索引值开始给定字符第一次出现的索引。

Kotlin的运算符

运算符是对操作数(值或变量)执行操作的特殊字符,Kotlin中有各种类型运算符:

  1. 算术运算符
  2. 关系运算符
  3. 赋值运算符
  4. 一元运算符
  5. 逻辑运算符
  6. 按位运算符

算术运算符

算术运算符用于执行基本的数学运算,如加法(+),减法(-),乘法(*),除法(/)等。

运算符功能表达式
+加法a+b
-减法a-b
*乘法a*b
/除法a/b
%取模(求余数)a%b

示例:

fun main(args : Array<String>) {
var a=10;
var b=5;
println(a+b);
println(a-b);
println(a*b);
println(a/b);
println(a%b);
}

关系运算符

关系运算符显示操作数之间的关系和比较。以下是几种常见的关系运算符:

运算符功能表达式
>大于a>b
<小于a<b
>=大于或等于a>=b
<=小于或等于a<=b
==相等a==b
!=不相等a!=b

示例:

fun main(args : Array<String>) {
    val a = 5
    val b = 10
    val max = if (a > b) {
        a
    } else{
        b
    }  //注意此处的if语句有返回值。
    println("max = $max")
}

赋值运算符

赋值运算符(=)用于将值赋给另一个变量。值的分配从右到左。

运算符功能表达式
=赋值a=b
+=相加和赋值a+=b
-=相减和赋值a-=b
*=相乘和赋值a*=b
/=相除和赋值a/=b
%=取模和赋值a%=b

示例:

fun main(args : Array<String>) {
    var a =20;
    var b=5
    a+=b
    a-=b
    a*=b
    a/=b
    a%=b
}

一元运算符

一元运算符仅与单个操作数一起使用。 以下是一些常用一元运算符。

运算符功能表达式
+变量取原数+a
-变量取相反数-a
++变量自加一a++,++a
变量自减一a–, --a
布尔变量取非!a

示例:

fun main(args : Array<String>) {
    var a=20
    var b=0
    b=a++ //a=21,b=20
    println("(a,b)=($a,$b)")
    b=--a  //a=20,b=20
    println("(a,b)=($a,$b)")
    var flag = true
    println(!flag)
}

逻辑运算符

逻辑运算符用于检查操作数之间的条件,与关系表达式连用。逻辑运算符列表如下:

运算符功能表达式
&&逻辑与(a>b) && (a>c)
||逻辑或(a>b) || (a>c)
逻辑非!a

示例:

fun main(args : Array<String>) {
var a=10
var b=5
var c=15
var flag = false
var result: Boolean = true
result = (a>b) && (a>c)
result = (a>b) || (a>c)
result = !flag
println(result)
}

按位运算

在Kotlin中,没有任何特殊的按位运算符,都是使用命名函数完成按位运算:

运算函数功能表达式
shl(bits)有符号左移a.shl(b)
shr(bits)有符号右移a.shr(b)
ushr(bits)无符号右移a.ushr(b)
and(bits)按位与a.and(b)
or(bits)按位或a.or(b)
xor(bits)按位异或a.xor(b)
inv()按位取反a.inv()
fun main(args : Array<String>) {
    var a=10 //1010
    var b=2//0010
    println("a.shl(b): "+a.shl(b)) //40
    println("a.shr(b): "+a.shr(b)) //2
    println("a.ushr(b:) "+a.ushr(b)) //2
    println("a.and(b): "+a.and(b)) //2
    println("a.or(b): "+a.or(b)) //10
    println("a.xor(b): "+a.xor(b)) //8
    println("a.inv(): "+a.inv())//-11
}

Kotlin的控制流程

Kotlin中有以下几种控制流程语句:

  1. if表达式
  2. when表达式
  3. for循环
  4. while循环
  5. do-while循环
  6. 返回和跳跃
  7. continue语句

if表达式

在Kotlin中,if表达式返回一个值。它用于控制程序结构的流程。 在Kotlin中有各种类型的if表达式:

  1. if-else表达式
  2. if-else if-else阶梯表达式
  3. 嵌套if表达式

在Kotlin中,if不能单独使用,必须与else表达式一起使用,if-else表达式的结果赋值给一个变量。

if-else表达式

if-else表达式的语法:

val returnValue = if (condition) {
    //code statement  
} else {
    // code statement  
}

示例:

fun main(args: Array<String>) {
    val num1 = 10
    val num2 =20
    val result = if (num1 > num2) {
        "$num1 is greater than $num2"
    } else {
        "$num1 is smaller than $num2"
    }
    println(result)
}

if-else if-else表达式

if-else if-else表达式的语法:

val returnValue = if (condition1) {
    //code statement  
}else if(condition2) {
   // code statement
}else {
    // code statement  
}

示例:

fun main(args: Array<String>) {
    val num = 10
    val result = if (num > 0){
        "$num is positive"
    }else if(num < 0){
        "$num is negative"
    }else{
        "$num is zero"
    }
    println(result)
}

嵌套if表达式

嵌套if表达式的语法:

val returnValue = if (condition1) {
    if-else code….
}else if(condition2) {
    if-else if-else code….
}else {
    // code statement  
}

示例:

fun main(args: Array<String>) {
    val num1 = 25
    val num2 = 20
    val num3 = 30
    val result = if (num1 > num2){
        val max = if(num1 > num3){
            num1
        }else{
            num3
             }
        "body of if "+max
    }else if(num2 > num3){
        "body of else if"+num2
    }else{
        "body of else "+num3
    }
    println("$result")
}
//body of if 30

When表达式

Kotlin when表达式是一个返回值的条件表达式。 Kotlin when表达式用于替换switch语句。 Kotlin when表达式相当于其他语言(C++,C)中的switch…case…语句。

示例:

//使用when作为表达式
fun main(args: Array<String>){
    var number = 4
    var numberProvided = when(number) {
        1 -> “One”
        2 -> “Two”
        3 -> “Three”
        else -> "invalid number"
    }
    println("You provide $numberProvided")
}
// invalid number
// 不使用when作为表达式
fun main(args: Array<String>){
    var number = 4
    when(number) {
        1 -> println("One")
        2 -> println("Two")
        3 -> println("Three")
        4 -> println("Four")
        5 -> println("Five")
        else -> println("invalid number")
    }
}
//Four
//when使用大括号的多重声明
fun main(args: Array<String>){
    var number = 1
    when(number) {
        1 -> {
            println("Monday")
            println("First day of the week")
        }
        7 -> println("Sunday")
        else -> println("Other days")
    }
}
//Monday
//First day of the week
//when多个分支
//以使用用逗号分隔的多个条件分支。当需要为多个选择运行相同的逻辑时就可以使用when多个分支。
fun main(args: Array<String>){
    var number = 8
    when(number) {
        3, 4, 5, 6 ->
        println("It is summer season")
        7, 8, 9 ->
        println("It is rainy season")
        10, 11 ->
        println("It is autumn season")
        12, 1, 2 ->
        println("It is winter season")
        else -> println("invalid input")
    }
}
//It is rainy season
//在范围(..)内使用when
//when表达式还检查条件提供的输入范围。 使用..(双点)运算符创建范围。 in运算符用于检查值是否属于某个范围。
fun main(args: Array<String>){
    var number = 7
    when(number) {
        in 1..5 -> println("Input is provided in the range 1 to 5")
        in 6..10 -> println("Input is provided in the range 6 to 10")
        else -> println("none of the above")
    }
}
//Input is provided in the range 6 to 10

For循环

Kotlin for循环用于迭代程序的一部分几次。 它遍历数组,范围,集合或提供迭代的任何内容。 Kotlin for循环等同于C#等语言中的foreach循环。

For循环的通用格式为:

for (item in collection){
    // 循环的主体 
}
//Collection表示集合
//Item表示Collection中的各项

示例:

fun main(args : Array<String>) {
    val marks = arrayOf(80,85,60,90,70)
    for(item in marks){
        println(item)
    }
}
//函数arrayOf()构造一个数组,Item表示数组中的元素。
//如果循环主题只有一条指令,则可以省略花括号{}
fun main(args : Array<String>) {
    val marks = arrayOf(80,85,60,90,70)
    for(item in marks)
    println(item)
}

基于数组的索引(index)迭代数组的元素。

示例:

fun main(args : Array<String>) {
    val marks = arrayOf(80,85,60,90,70)
    for(item in marks.indices)
    println("marks[$item]: "+ marks[item])
}
//其中,数组的成员变量indices表示数组中元素的个数。此时,item表示数组元素的索引值(index)。
//在For循环中使用Kotlin的范围(..)语句
fun main(args : Array<String>) {
    for (i in 1..5) print(i)
    for (i in 5..1) print(i)             
    for (i in 5 downTo 1) print(i)
    for (i in 5 downTo 2) print(i)
    for (i in 1..5 step 2) print(i)
    for (i in 5 downTo 1 step 2) print(i)
}
// 1..5 表示范围1,2,3,4,5
// 5..1 表示范围5,4,3,2,1
// 5 downTo1 等价于 5..1
// 5 downTo2 等价于 5..2
// 1..5 step 2 表示范围1,3,5
// 5 downTo 1 step2 表示范围 5,3,1

While循环

while循环用于多次迭代程序的一部分。条件为真时一直循环执行代码块。 Kotlin while循环类似于Java while循环。

While循环的通用格式:

while(condition){
    // 循环主体
}

示例:

fun main(args: Array<String>){
    var i = 1
    while (i<=5){
        println(i)
        i++
    }
}
fun main(args: Array<String>){
    while (true){
        println("infinite loop")
    }  
}

Do-While循环

•do-while循环类似于while循环,但是有一个关键区别:do-while循环首先执行do块的主体,然后检查while的条件。

Do-While循环的格式:

do{
    // do块的主体
}
while(condition);

示例:

fun main(args: Array<String>){
    var i = 1
    do {
        println(i)
        i++
    }
    while (i<=5);
}
fun main(args: Array<String>){
    var i = 1
    do {
        println(i)
        i++
    }
    while (i<=5);
}

返回和跳跃语句

Kotlin中有三个跳跃表达式。 这些跳转表达式用于控制程序执行的流程。 这些跳跃语句是:

  1. Break
  2. Continue
  3. Return // Return比较复杂,放在“函数”里讲。

Break语句

Break语句用于终止最近的封闭循环。 它一般与if-else条件一起使用。

语法格式:

for(..){
    // for主体
    if(checkCondition){
        break
    }
}
//for循环在if条件执行break语句时终止它的循环。 

示例:

fun main(args: Array<String>) {
    for (i in 1..5) {
        if (i == 3) {
            break
        }
        println(i)
    }
}

标记Break语句

标记是标识符的形式,后跟@符号,例如abc@,test@。

Kotlin标记break语句用于终止特定的循环。 这是通过使用带有@符号后跟标签名称的break语句(break@loop)来完成的。

示例:

fun main(args: Array<String>) {
    loop@ for (i in 1..3) {
        for (j in 1..3) {
            println("i = $i and j = $j")
            if (i == 2)
            break@loop
        }
    }
}

Continue语句

Kotlin的continue语句用于循环中,它继续当前程序流并在指定条件下跳过本次循环体剩余代码,进入使程序流下一次循环体。

语法格式:

for(..){
    // for中的if语句上部分主体
    if(checkCondition){
        continue
    }
    //for中的if语句下部分主体
}

示例:

fun main(args: Array<String>) {
    val j:Int = 0
    for (i in 1..3) {
        println("i = $i")
        if (j == 2) {
            continue
        }
        println("this is below if")
    }
}

标记Continue语句

标记是标识符的形式,后跟@符号,例如abc@,test@。

标记为continue语句,在Kotlin中用于重复特定的循环(标记的循环)。 通过使用带有@符号后跟标签名称的continue语句(continue@labelname)来完成的。

示例:

fun main(args: Array<String>) {
    labelname@ for (i in 1..3) {
        for (j in 1..3) {
            println("i = $i and j = $j")
            if (i == 2) {
                continue@labelname
            }
            println("this is below if")
        }
    }
}

Kotlin函数

函数是执行特定任务的一组相互关联的代码块。函数用于将程序分解为不同的子模块。 它使代码可重用,并使程序更易于管理。

Kotlin使用fun关键字声明函数,支持两种类型:

  1. 标准库函数
  2. 用户自定义函数

标准库函数

Kotlin标准库函数是内置库函数,它隐式存在于库中并可供使用。

示例:

fun main(args: Array<String>){
    var number = 25
    var result = Math.sqrt(number.toDouble())
    print("The square root of $number is $result")
}
//这里,sqrt()是一个库函数,它返回一个数字的平方根(Double类型值)。print()也是一个库函数,它将消息输出到标准输出流。

Kotlin标准库函数手册:https://kotlinlang.org/api/latest/jvm/stdlib/

用户自定义函数

用户定义的函数是由用户创建的函数。用户定义的函数接受参数,执行操作并将该操作的结果作为值返回。

Kotlin函数使用fun关键字声明:

fun functionName(){
    // 函数体
}

需要通过调用函数来在函数主体内运行代码。

functionName()

示例:

fun main(args: Array<String>){
    sum()
    print("code after sum")
}
fun sum(){
    var num1 = 5
    var num2 = 6
    println("sum = "+(num1+num2))
}

Kotlin参数化函数和返回值

函数也可将参数作为参数并返回值。 Kotlin函数使用name: type(参数名称及其类型)。 函数中的参数使用逗号分隔。如果函数无返回值,则返回类型为Unit。

无返回值函数

fun functionName1(number1: Int, number2: Int){
    //.. .. ..
}

有返回值函数

fun functionName2(number1: Int, number2: Int):Int{
    //.. .. ..
    return 0
}

示例:

fun main(args: Array<String>){
    val result = sum(5, 8)
    print("两个数相加的结果是:"+result)
}
fun sum(number1: Int, number2:Int): Int{
    val result = number1+number2
    return result
}
// sum函数的返回值类型为int

Kotlin的递归函数

递归函数是一个连续调用自身的函数

递归函数:

fun functionName(){
    .. .. ..
    functionName() //调用函数自身 
}

递归函数示例1:有限次数

var count = 0
fun rec(){
    count++;
    if(count<=5){
        println("count => "+count);
        rec();
    }
}
fun main(args: Array<String>) {
    rec();
}

递归函数示例2:阶乘数

fun main(args: Array<String>) {
    val number = 5
    val result: Long
    result = factorial(number)
    println("Factorial of $number = $result")
}

fun factorial(n: Int): Long {
    return if(n == 1){
        n.toLong()
    }
    else{
        n*factorial(n-1)
    }
}

Kotlin的尾递归函数

•kotlin中,如果某个函数的末尾又调用了函数自身,这种就称为尾递归函数。

•尾递归函数需要在 fun 前面添加 tailrec。

•尾递归函数会使用循环的方式替代递归,从而避免栈溢出。

•尾递归不能在异常处理的try、 catch 、 finally 块中使用 。、

例:计算连续n个自然数(上限为100000)之和

一般递归:

fun main(args: Array<String>) {
    var result = recursiveSum(100000)
    println(result)
}
fun recursiveSum(n: Long) : Long {
    return if (n <= 1) {
        n
    } else {
        n + recursiveSum(n - 1)
    }
}
//Exception in thread "main" java.lang.StackOverflowError

尾递归:

fun main(args: Array<String>) {
    var number = 100000.toLong()
    var result = recursiveSum(number)
    println("sum of upto $number number = $result")
}
tailrec fun recursiveSum(n: Long, semiresult: Long = 0) : Long {
    return if (n <= 0) {
        semiresult
    } else {
        recursiveSum( (n - 1), n+semiresult)
    }
}

函数参数的默认值和命名参数

Kotlin提供了在函数定义中指定默认参数的工具。如果调用函数而不传递任何参数,则使用默认参数作为函数的参数;而当使用参数调用函数时,传递参数将用作函数的参数。

示例:

fun main(args: Array<String>) {
    run()
}
fun run(num:Int= 5, latter: Char ='x'){
    print("parameter in function definition $num and $latter")
}
//在上面的程序中,run()函数调用没有传递参数,它使用在函数定义中的默认参数。
fun main(args: Array<String>) {
    run(45)     //正确
    run( 30,‘z’)//正确
    run(‘A’)     //错误,将‘A’误认为num的参数
    run(latter = 'A') //正确
}
fun run(num:Int= 5, latter: Char ='x'){
    println("parameter in function definition $num and $latter")
}

Lambda函数

Lambda是一个没有名字的函数。 Lambda是用花括号{}定义的,它将变量作为参数(如果有的话)和函数体。 函数体在变量(如果有)之后写入,后跟 -> 运算符。

Lambda函数的基本格式:{variable -> body_of_function}

fun main(args: Array<String>){
    val myLambda: (Int) -> Unit= {s: Int -> println(s) }
    addNumber(5,10,myLambda)
}
fun addNumber(a: Int, b: Int, mylambda: (Int) -> Unit ){   //high level function lambda as parameter  
    val add = a + b
    mylambda(add) // println(add)  
}
//15

高阶函数

  • 高阶函数是将函数用作参数或返回值的函数。如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数称为高阶函数。
  • 目的:高阶函数允许让函数类型参数决定函数的执行逻辑,即使同一个高阶函数,传入的函数类型参数不同,那么函数的执行逻辑和返回结果可能也是完全不同的。
fun myFun(org: String,portal: String, fn: (String,String) -> String): Unit {
    val result = fn(org,portal)
    println(result)
}
//myFun()的作用是将org和portal用fn处理成result,并打印result。(fn需要另行定义,为其它函数的返回值。)
//myFun()的功能依赖fn的定义!
  1. 使用三个参数定义了一个函数myFun():
    • org:String类型
    • portal:String类型
    • fn: String类型,但fn是把(String, String)组合起来作为输入,把String作为输出。
  2. myFun()的输出为Unit类型(无返回值)

示例:

fun myFun(org: String,portal: String, fn: (String,String) -> String): Unit {
    val result = fn(org,portal)
    println(result)
}

fun main(args: Array<String>){
    val fn:(String,String)->String={org,portal->"$org develop $portal"}
    myFun("yiibai.org","yiibai.com",fn)
}
//yiibai.org develop yiibai.com

Lambda函数的作用:把两个参数(String类型)组合为fn(String类型)。

主程序中myFun函数的作用:把两个字符串yiibai.org和yiibai.com让Lambda函数进行处理,Lambda函数的返回值为fn(String类型)。

示例:

//高阶函数允许让函数类型参数决定函数的执行逻辑!
fun myFun(org: String,portal: String, fn: (String,String) -> String): Unit {
    val result = fn(org,portal)
    println(result)
}
fun main(args: Array<String>){
    val fn:(String,String)->String={org,portal->"$org develop $portal"}
    val fn1:(String,String)->String={a,b->"$a kills $b"}
    myFun("yiibai.org","yiibai.com",fn)
    myFun("Tom","Jerry",fn1)
}
//yiibai.org develop yiibai.com
//Tom kills Jerry

Kotlin的异常处理

异常是程序中发生的运行时问题,导致程序终止。 这可能是由于内存空间不足,数组越界,条件除以零等而发生的。 要在程序执行期间处理这种类型的问题,可使用异常处理技术。

异常处理是一种处理运行时问题并维护程序执行流程的技术。在Kotlin中,所有异常类都是Throwable类的子类。 要抛出异常对象,Kotlin使用throw表达式。

throw表达式的格式:

throw MyException("this throws an exception")

异常处理中使用四种关键字:

关键字释义
trytry块包含可能生成异常的语句集,必须后跟catch 或 finally或两者。
catchcatch块用于捕获try块抛出的异常。
finallyfinally块始终执行是否处理异常,用于执行重要的代码语句。
throwthrow关键字用于显式抛出异常。

Kotlin程序中未经检查的异常

未经检查的异常是由于代码中的错误而引发的异常。 此异常类型扩展了RuntimeException类。在运行时检查未经检查的异常。 以下是未经检查的异常的一些示例:

异常名称释义
ArithmeticException当将数字除以零时抛出。
ArrayIndexOutOfBoundExceptions尝试使用不正确的索引值访问数组时抛出。
SecurityException由安全管理器抛出以指示安全性违规。
NullPointerException在null对象上调用方法或属性时抛出。

Kotlin异常处理操作格式

Kotlin异常处理有三种格式:try-catch、try-finally、try-catch-finally

try-catch

try{
    //code that may throw exception    
}catch(e: SomeException){
    //code that handles exception  
}

try-finally

try{
    //code that may throw exception    
}
finally{
    // code finally block  
}

try-catch-finally

try {
    // some code  执行可能存在异常的代码
}
catch (e: SomeException) {
    // handler  异常处理
}
finally {
    // optional finally block  必须执行的收尾工作

}

示例:

fun main(args: Array<String>){
    val data = 20 / 0   //may throw exception
    println("code below exception") //不执行
}
//Exception in thread "main" java.lang.ArithmeticException: / by zero

上面的程序生成一个异常,导致低于的异常代码的其余部分不可执行。

fun main(args: Array<String>){
    try {
        val data = 20 / 0  //may throw exception  
    } catch (e: ArithmeticException) {
        println(e)//可执行
    }
    println("code below exception...") //可执行
}
//java.lang.ArithmeticException: / by zero
//code below exception...

包含多个catch块的异常处理示例:

fun main(args: Array<String>){
    try {
        val a = IntArray(5)
        a[5] = 10 / 0
    } catch (e: ArithmeticException) {
        println("arithmetic exception catch") //只执行这个catch
    } catch (e: ArrayIndexOutOfBoundsException) {
        println("array index outofbounds exception")//不执行
    } catch (e: Exception) {
        println("parent exception class")//不执行
    }
    println("code after try catch...")//执行
}
//arithmetic exception catch
//code after try catch...

嵌套型异常处理:

fun main(args: Array<String>) {
    val nume = intArrayOf(4, 8, 16, 32, 64, 128, 256, 512)
    val deno = intArrayOf(2, 0, 4, 4, 0, 8)
    try {
        for (i in nume.indices) {
            try {
                println(nume[i].toString() + " / " + deno[i] + " is " + nume[i] / deno[i])
            } catch (exc: ArithmeticException) {
                println("Can't divided by Zero!")
            }
        }
    } catch (exc: ArrayIndexOutOfBoundsException) {
        println("Element not found.")
    }
}
//4 / 2 is 2
//Can't divided by Zero!
//16 / 4 is 4
//32 / 4 is 8
//Can't divided by Zero!
//128 / 8 is 16
//Element not found.

Kotlin finally是这样的块:无论是否处理异常,它总是执行, 所以它用于执行重要的代码语句。

正常情况

fun main (args: Array<String>){
    try {
        val data = 10 / 5
        println(data)
    } catch (e: NullPointerException) {
        println(e)
    } finally {
        println("finally block always executes") //总是运行
    }
    println("below codes...")
}
//2
//finally block always executes
//below codes...

异常情况且不处理

fun main (args: Array<String>){
    try {
        val data = 10 / 0
        println(data)
    } catch (e: NullPointerException) {
        println(e)
    } finally {
        println("finally block always executes")//总是执行
    }
    println("below codes...") //不执行
}
//finally block always executes
//Exception in thread "main" java.lang.ArithmeticException: / by zero

异常情况且处理

fun main (args: Array<String>){
    try {
        val data = 10 / 0
        println(data)
    } catch (e: ArithmeticException) {
        println(e)
    } finally {
        println("finally block always executes")//总是执行
    }
    println("below codes...")//执行
}
//java.lang.ArithmeticException: / by zero
//finally block always executes
//below codes...

Kotlin的throw关键字

Kotlin throw关键字用于抛出显式异常,它可以用于抛出自定义异常。

此示例演示验证驾驶执照的年龄限制:

fun main(args: Array<String>) {
    validate(15)
    println("code after validation check...")
}
fun validate(age: Int) {
    if (age < 18)
    throw ArithmeticException("under age")
    else
    println("eligible for drive")
}
//Exception in thread "main" java.lang.ArithmeticException: under age

Kotlin的空安全性

  • Kotlin null安全性是一种消除代码中空引用风险的过程。 如果Kotlin编译器发现任何null参数而仍然执行null引用相关语句,则会立即抛出NullPointerException。
  • Kotlin的类型系统旨在消除代码中的NullPointerException。

kotlin的可空类型和非可空类型

Kotlin类型系统区分可以保持null(可空引用)和不能保持null(非null引用)的引用。

非可空类型

var String=“Hello”

可空类型

var String?=“Hello”

变量名后加?表示定义变量为可空类型。

可控变量示例:

fun main(args: Array<String>){
    var str: String? = "Hello" // 变量被声明为可空
    str = null
    print(str) //打印null
}

image-20220921164112702

特别注意:可空变量在使用前通常需要进行非空检查!

非可空变量示例:

fun main(args: Array<String>){
var str: String = "Hello" //变量不可为空
str = null // compile error  
print(str)
}

image-20220921164238293

Kotlin的if表达式用于检查条件并返回值。

示例:

fun main(args: Array<String>){
    var str: String? = "Hello"     // variable is declared as nullable
    var len = if(str!=null) str.length else -1
    println("str is : $str")
    println("str length is : $len")
    str = null
    println("str is : $str")
    len = if(str!=null) str.length else -1
    println("b length is : $len")
}

image-20220921164433422

Kotlin智能类型转换

当尝试在没有安全转换的情况下访问可空类型的String时,它将生成编译错误。

示例:

var string: String? = "Hello!"
print(string.length) // Compile error

image-20220921164756525

fun main(args: Array<String>){
var string: String? = "Hello!"
if(string != null) { // smart cast  
print(string.length) // It works now!  
}
}

image-20220921164718534

使用is和!is检查变量类型

使用is或!is来检查变量时,编译器会跟踪此信息并在内部将变量转换为目标类型。

示例:

fun main(args: Array<String>){
var obj:String?="123456"
if(obj is String) {
println("obj is a string")
}
obj = null
if(obj !is String) {
println("obj is not a string")
}
}

image-20220921165002086

使用as和!as进行变量类型转换

不安全的转换操作符:as

有时无法转换变量并抛出异常,这称为不安全转换。 不安全的强制转换由中缀运算符执行。可以为空的字符串(String?)不能转换为非null字符串(String),这会引发异常。在Kotlin中,父类是禁止转换为子类型的。

示例:

fun main(args: Array<String>){
    val obj: Any? = null
    val str: String = obj as String // 看这
    println(str)
}

image-20220921165243038

fun main(args: Array<String>){
    val obj: Any? = null
    val str: String? = obj as String? // 看这
    println(str)
}

image-20220921165413278

示例:

fun main(args: Array<String>){
    val obj: Any = 123
    val str: String = obj as String
}

image-20220921165541757

fun main(args: Array<String>){
    val obj: Any = 123
    val num: Int = obj as Int
}

image-20220921165736395

Kotline的安全转换符:as?

Kotlin提供安全转换操作符:as? 安全地转换成一种类型。 如果无法进行转换,则返回null,而不是抛出ClassCastException异常。

示例:

fun main(args: Array<String>){
val location: Any = "Kotlin"
val safeString: String? = location as? String //这里as也可以 因为location不是空值
val safeInt: Int? = location as? Int
println(safeString)
println(safeInt)
}

image-20220921165908717

as?是工程上比较常用的类型转换操作符。

Kotlin Elvis运算符

Elvis运算符(?:)用于返回非null值,即使条件表达式为null。

var str: String? = null
var str2: String? = "May be declare nullable string"

在上面的代码中,str包含一个null值,在访问str的值之前需要执行安全检查,字符串是否包含值。

在传统方法中,使用if…else语句执行此安全检查。

var len1: Int = if (str != null) str.length else -1
var len2: Int = if (str2 != null) str.length else -1

Kotlin提供称为Elvis运算符(?:)的高级运算符,即使条件表达式为空,也返回非空值

var len1:  Int = str?.length ?: -1
var len2:  Int = str2?.length ?:  -1

如果str不为null,Elvis运算符返回 (str ?.length);否则它返回-1。

Kotlin的集合

Kotlin中的集合用于在一个单元中存储一组相关对象。通过使用集合,可以存储,检索操作和聚合数据。

Kotlin中的集合用于在一个单元中存储一组相关对象。通过使用集合,可以存储,检索操作和聚合数据。

  • 不可变集合
  • 可变集合

不可变集合

不可变集合也称为集合支持只读功能。支持读取功能的不可变集合的方法是:

集合类型不可变集合方法
ListlistOf(), listOf()
MapmapOf()
SetSetof()

表示泛型,应用时可具体化为String、Int等。

可变集合

可变集合支持读写功能。支持读写功能的可变集合的方法是:

集合类型可变集合方法
ListmutableListOf(), mutableListOf()
MapmutableMapOf()
SetmutableSetOf()

List(python的list)

Kotlin List是一个接口和通用的元素集合。 List接口继承了Collection 类的形式。 它是不可变的,它的方法只支持读取功能。

部分List接口函数

函数描述
abstract fun contains(element: E): Boolean它检查指定的元素是否包含在此集合中。
abstract fun containsAll(elements: Collection): Boolean它检查指定的所有元素是否包含在此集合中。
abstract operator fun get(index: Int): E它返回列表中给定索引处的元素。
abstract fun indexOf(element: E): Int返回列表中第一次出现的指定元素的索引,如果列表中不存在指定的元素,则返回-1。
abstract fun isEmpty(): Boolean如果列表为空,则返回true,否则返回false。
abstract fun lastIndexOf(element: E): Int它返回列表中最后一次出现的指定元素的索引,如果列表中不存在指定的元素,则返回-1。
abstract fun subList(fromIndex: Int, toIndex: Int): List它返回列表的fromIndex(包括)和toIndex(不包括)索引之间的部分。

Kotlin List示例1

fun main(args: Array<String>) {
var list = listOf("Ajax", "Vivi", "Praka")//read only, fix-size
for (element in list) {
println(element)
}
}

image-20220921172607159

Kotlin List示例2

fun main(args: Array<String>){
var list = listOf(1,2,3,"Ajax","Vivi","Praka")//read only, fix-size  
for(element in list){
println(element)
}
println("-------------- 使用范围遍历 -------------------- ")
for(index in 0..list.size-1){
println(list[index])
}
}

image-20220921182311843

在listOf()函数中,可以同时传递不同类型的数据。

Kotlin List示例3

fun main(args: Array<String>){
    var intList: List<Int> = listOf<Int>(1,2,3)
    var anyList: List<Any> = listOf<Any>(1,2,3,"Ajax","Vivi","Yiibai") //listOf()的泛型类型
    println("print int list")
    for(element in intList){
        println(element)
    }
    println("--------------------------")
    println("print any list")
    for(element in anyList){
        println(element)
    }
}

image-20220921182436408

Kotlin List示例4

fun main(args: Array<String>){
var stringList: List<String> = listOf<String>("Ajax","Vivi","Prakash","Vivi","Rohan")
var list: List<String> = listOf<String>("Ajax","Vivi","Prakash")
for(element in stringList){
print(element+" ")
}
println()
println(stringList.get(0))
println(stringList.indexOf("Vivi"))
println(stringList.lastIndexOf("Vivi"))
println(stringList.size)
println(stringList.contains("Prakash"))
println(stringList.containsAll(list))
println(stringList.subList(2,4))
println(stringList.isEmpty())
println(stringList.drop(1))
println(stringList.dropLast(2))
} //list的接口函数

image-20220921182841957

MutableList

MutableList本质上是可变的。 它继承了Collection 类的形式。 MutableList的方法支持读写功能,可以添加更多元素或删除它们,没有固定的长度。

要使用MutableList,需要使用mutableListOf()或mutableListOf ()函数。

MutableList示例

fun main(args: Array<String>){
var mutableList = mutableListOf("Ajax","Maxsu","Praka","Maxsu")
for(element in mutableList){
println(element)
}
println()
for(index in 0..mutableList.size-1){
println(mutableList[index])
}
}

image-20220921183239875

MutableList常用函数

函数功能
abstract fun add(element: E): Boolean它将给定元素添加到集合中。
abstract fun add(index: Int, element: E)它在指定的索引处添加元素。
abstract fun addAll(elements: Collection): Boolean它将给定集合的所有元素添加到当前集合中。
abstract fun clear()它会删除此集合中的所有元素。
abstract fun remove(element: E): Boolean如果指定的元素存在于当前集合中,它将删除它。
abstract fun removeAll(elements: Collection): Boolean它会删除当前列表中也存在于指定集合中的所有元素。
abstract fun removeAt(index: Int): E它从列表中删除给定索引处的元素。
abstract fun retainAll(elements: Collection): Boolean它保留当前集合中存在于给定集合中的所有元素(交集)。
abstract operator fun set(index: Int, element: E): E它替换元素并在给定索引处添加指定元素。

示例

fun main(args: Array<String>){
    var mutableList1 = mutableListOf("Ajax","Vijax")
    mutableList1.add("Praka")
    mutableList1.add("Vijax")
    var mutableList2 = mutableListOf<String>()
    mutableList2.add("A1")
    mutableList2.add("A2")
    mutableList2.add("A3")
    for(element in mutableList1){
        println(element)
    }
        println()
    for(element in mutableList2){
        println(element)
    }
}

image-20220921183438916

示例:

fun main(args: Array<String>){
    var mutableList = mutableListOf<String>()
    mutableList.add("A1") // index 0
    mutableList.add("V1") // index 1
    mutableList.add("P1") // index 2
    var mutableList2 = mutableListOf<String>("R1","R12")
    var mutableList3 = mutableListOf<String>("D3","U3")
    var mutableList4 = mutableListOf<String>("A1","D4","A4")
    mutableList.add(2,"Rx")
    println(mutableList)
    mutableList.addAll(1,mutableList3)
    println(mutableList)
    mutableList.addAll(mutableList2)
    println(mutableList)
    mutableList.remove("V1")
    println(mutableList)
    mutableList.removeAt(2)
    println(mutableList)
    mutableList.removeAll(mutableList2)
    println(mutableList)
    mutableList.set(2,"As")
    println(mutableList)
    if(mutableList.retainAll(mutableList4)){
        println("Yes...")
    }
    mutableList2.clear()
    println(mutableList2)
    println(mutableList.subList(0,1))
}

image-20220921184137116

Map(python的dict)

  • Map以键值对的形式保存数据。 映射的键是唯一的,每个键只保留一个值。 键和值可以是不同类型的对,例如<Int,Int>,<Int,String>,<Char,String>等。
  • map是不可变的,它的大小固定,方法支持只读访问。
  • 要使用Map,需要使用mapOf()或mapOf <k,v>()函数。

Map示例1:

下面使用mapOf <k,v>()函数声明和遍历Map值的示例。 在这个例子中,创建Int类型的键和String类型的值。

fun main(args: Array<String>){
val myMap = mapOf<Int,String>(1 to "Java", 4 to "Kotlin", 3 to "Python")
for(key in myMap.keys){
println(key.toString() +" => "+myMap[key])
}
}

image-20220921184316810

Map 常用函数

函数功能
fun <K, V> Map<key, value>.getValue(key: K): V它返回给定键的值,如果映射中没有这样的键,则抛出异常。
fun <K, V> Map<out K, V>.contains(key: K): Boolean它检查在Map中是否包含给定的键。
fun Map<out K, *>.containsKey(key: K): Boolean如果Map包含指定的键,则返回true
fun <K, V> Map<K, V>.containsValue(value: V): Boolean如果map有将一个或多个键映射到指定值,则返回true。
fun <K, V> Map<out K, V>.getOrDefault(key: K,defaultValue: V ): V它返回由映射中的键对应的值,或者如果map不包含给定键的映射,则返回默认值。
operator fun <K, V> Map<out K, V>.plus(pair: Pair<K, V>): Map<K, V>它通过从给定键值对向当前映射添加或替换数据项目来创建新的只读映射。
operator fun <K, V> Map<out K, V>.minus(keys: Sequence): Map<K, V>它返回一个映射,其中包含原始映射的所有数据项目,除了那些包含在给定键序列中的数据项目键。

Map示例2 - 泛型

泛型类型Map,例如myMap:Map <k,v> = mapOf <k,v>()。

val myMap: Map<Int, String> = 
mapOf<Int,String>(1 to "Maxsu", 4 to "Kotlin", 3 to "Java")

Map示例3 - 非泛型

如果不能指定Map接口的任何类型的键和值,那么它可以采用不同类型的键和值。 这是因为所有类内部都使用<Any,Any>类型。

val myMap = 
mapOf(1 to "Java", 4 to "Python", 3 to "PHP","one" to "Yiibai", "two" to 2)

Map 常用函数应用示例

fun main(args: Array<String>){
val myMap: Map<Int,String> = mapOf<Int, String>(1 to "Java", 4 to "Kotlin", 3 to "Python")
for(key in myMap.keys){
println("Element at key $key = ${myMap.get(key)}")
}
println(".....myMap.getValue(4).......")
println(myMap.getValue(4))
println(".....myMap.contains(3).......")
println( myMap.contains(3))
println("......myMap.containsKey(2)......")
println(myMap.containsKey(2))
println("......myMap.containsValue(\"Susen\")......")
println(myMap.containsValue("Susen"))
println(".....myMap.get(1).......")
println(myMap.get(1))
println("......myMap.minus(4)......")
for(m in myMap.minus(4)){
println(myMap[m.key])
}
println("......myMap.plus(Pair(5, \"Swift\"))......")
for(p in myMap.plus(Pair(5, "Swift"))){
println("Element at key ${p.key} = ${p.value}")
}
}

image-20220921184925268

MutableMap

MutableMap以键和值对的形式保存对象。 使用相应的键来检索MutableMap接口的值。键和值可以是不同类型的对,例如<Int,Int>,<Int,String>,<Char,String>等等。MutableMap的每个键只保存一个值。MutableMap中的键值可以进行增删操作。

要使用MutableMap接口,需要使用它的函数:mutableMapOf()或mutableMapOf <k,v>()。

mutableMap声明示例:

val mutableMap1: MutableMap<Int, String> = mutableMapOf<Int, String>(1 to "Java", 4 to "Ruby", 2 to "Ajax", 3 to "Vivi")
val mutableMap2: MutableMap<String, String> = mutableMapOf<String, String>()
//声明一个空mutableMap

MutableMap 常用函数

函数功能
abstract fun put(key: K, value: V): V?使用映射中的指定键添加给定值。
abstract fun putAll(from: Map<out K, V>)使用指定映射中的键/值对更新当前映射。
abstract fun remove(key: K): V?从映射中删除指定的键及对应的值。
open fun remove(key: K, value: V): Boolean仅当映射中存在键和值实体时,它才会从映射中删除它们。
abstract fun clear()此函数用于从映射中删除所有元素。
abstract fun containsKey(key: K): Boolean如果map包含指定的键,则返回true。
fun Map<out K, *>.containsKey(key: K): Boolean如果map包含指定的键,则返回true。
abstract fun containsValue(value: V): Boolean如果映射包含给定值的一个或多个键,则返回true。
fun <K, V> Map<K, V>.containsValue(value: V): Boolean如果映射包含给定值的一个或多个键,则返回true。
fun <K, V> Map<out K, V>.count(): Int它返回映射的项目总数。
operator fun <K, V> Map<out K, V>.get(key: K): V?它返回与键对应的值,如果在映射中找不到指定键,则返回null。
fun <K, V> Map<K, V>.getValue(key: K): V它返回与给定键对应的值,如果在映射中找不到键,则抛出异常。

MutableMap示例

fun main(args: Array<String>) {
val mutableMap1: MutableMap<Int, String> = mutableMapOf<Int, String>(1 to "Java", 4 to "Ruby", 2 to "Ajax", 3 to "Vivi")
val mutableMap2: MutableMap<String, String> = mutableMapOf<String, String>()
mutableMap2.put("name", "Susen")
mutableMap2.put("city", "Haikou")
mutableMap2.put("department", "R&D")
mutableMap2.put("hobby", "programming")
val mutableMap3: MutableMap<Any, Any> = mutableMapOf<Any, Any>(1 to "Maxsu", "name" to "Ruby", 2 to 200)
println(".....traverse mutableMap1........")
for (key in mutableMap1.keys) {
println("Key = ${key}, Value = ${mutableMap1[key]}")
}
println("......traverse mutableMap2.......")
for (key in mutableMap2.keys) {
println("Key = "+key +", "+"Value = "+mutableMap2[key])
}
println("......traverse mutableMap3......")
for (key in mutableMap3.keys) {
println("Key = ${key}, Value = ${mutableMap3[key]}")
}
}

image-20220921185250183

MutableMaps示例2

fun main(args: Array<String>) {
val mutableMap: MutableMap<String, String> = mutableMapOf<String, String>()
mutableMap.put("name", "Maxsu")
mutableMap.put("city", "Haikou")
mutableMap.put("department", "Development")
mutableMap.put("hobby", "programming")
println("......traverse mutableMap.......")
for (key in mutableMap.keys) {
println("Key = ${key}, Value = ${mutableMap[key]}")
}
println("......mutableMap.remove(\"city\").......")
println(mutableMap.remove("city"))
println(".......mutableMap.remove(\"hobby\",\"programming\")......")
println(mutableMap.remove("hobby","programming"))
println("......traverse mutableMap.......")
for (key in mutableMap.keys) {
println("Key = ${key}, Value = ${mutableMap[key]}")
}
}

image-20220921185438488

Set(python的set)

•Set接口是一个通用的无序元素集合,Set不支持重复元素。 Set是不可变的,它的方法支持集合的只读功能。

Set使用setOf()函数创建包含元素列表的Set接口对象列表。

fun main(args: Array<String>){
val intSet = setOf(12,16,24,29,4,5)
val mySet: Set<Any> = setOf(12,16,24,29,4,5,"Java","Ajax")
println(".......print Int set.........")
for(element in intSet){
println(element)
}
println(".......print Any set.........")
for(element in mySet){
println(element)
}
}

image-20220921185711794

Set 集合常用方法

fun main(args: Array<String>) {

    val set = setOf("kotlin", "java", "swift", "flutter")
// set 转 map
    val setToMap = set.associateBy { "${it.length}" }
    println(setToMap) // {6=kotlin, 4=java, 5=swift, 7=flutter}

// set 判断包含关系
    set.contains("kotlin")
    println("kotlin" in set) // true
    println("swift" !in set) // false

// 获取删除 set 集合前面 n 个元素的集合
    println(set.drop(3)) // [flutter]

// 过滤 set 中含有 ft 的元素集合
    println(set.filter { "ft" in it }) // [swift]

// 找出 set 中含有 ft 的元素,找不到就是null
    println(set.find { "ft" in it }) // swift
    println(set.find { "python" in it }) // null

// 拼接集合中的元素
    println(set.fold("") { acc, ele -> acc + ele }) // kotlinjavaswiftflutter

// 查找元素索引
    println(set.indexOf("kotlin")) // 0

// 获取最大值,最小值
    println(set.maxOrNull()) // swift
    println(set.minOrNull()) // flutter

// 反转集合
    println(set.reversed()) // [flutter, swift, java, kotlin]

    val setStr = setOf("flutter", "oc")
// 计算2个集合的交集
    println(set intersect setStr) // [flutter]

// 计算2个集合的并集
    println(set union setStr) // [kotlin, java, swift, flutter, oc]

}

image-20220921190052778

MutableSet

MutableSet是一个通用的无序元素集合,不支持重复元素。 MutableSet是可变的,它的方法支持集合的读写增删等功能。

使用mutableSetOf()函数创建象。

MutableSet提供了add(element:E)方法来添加元素,每调用该方法一次,就会向Set中添加一个元素,Set的长度也会自动加1.

提供了addAll(elements:Collection)方法来批量添加多个元素。

MutableSet提供了如下方法来删除元素:

remove(element:E):删除指定元素,删除成功则返回true。
removeAll(elements:Collection):批量删除Set集合中的多个元素。
retainAll(elements:Collection):只保留Set集合中与elements集合共有的元素。
clear():清空集合。

示例:创建和遍历mutableset

fun main(args: Array<String>) {
val intmutableSet = mutableSetOf<Int>(2, 6, 4, 29, 4, 5)
val anymutableSet: Set<Any> = setOf(2, 6, 4, 29, 4, 5, "Ajax", "Susen", "Ajax") //元素不能重复
println("....intmutableSet....")
for(element in intmutableSet){
println(element)
}
println("....anymutableSet......")
for(element in anymutableSet){
println(element)
}
}

image-20220921185845210

示例:增加删除set元素

fun main(args: Array<String>) {
    //定义一个可变的Set
    var languages = mutableSetOf("Java")
    //添加一个元素
    languages.add("Go")
    languages.add("Lua")
    println(languages)
    println(languages.count())
    languages.addAll(setOf("Swift", "Kotlin"))
    println(languages)

}

image-20220921190425609

fun main(args: Array<String>) {
    //定义一个可变的Set
    var languages = mutableSetOf("Java", "OC", "PHP", "Perl", "Ruby", "Go")
    //删除"PHP"
    languages.remove("PHP")
    //再次删除"Perl"
    languages.remove("Perl")
    println(languages)
    //批量删除多个元素
    languages.removeAll(setOf("Ruby", "Go"))
    println(languages)
    //清空Set集合
    languages.clear()
    println(languages.count())
}

image-20220921190515944

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值