//list创建和元素获取
//创建list,但是是不可变的
val list = listOf("Jason", "jack", "jonse")
// println(list[3])//报异常
//getorElse是一个安全索引取值函数,它需要两个参数,第一个是索引值,第二个是能提供默认值的lambda表达式,如果索引值不存在,可用来代替异常
println(list.getOrElse(3) {
"unknown"})
//另一个安全索引取值函数,它返回null结果,而不是抛出异常,因此适用于空安全运算符
println(list.getOrNull(3)?:"unknown")
-
mutator函数
能修改可变列表的函数有一个统一的名字:mutator函数
添加元素运算符 += 与删除元素运算符 -=
//可变列表
val mutableListOf = mutableListOf("Jason", "jack", "jonse")
// mutableListOf.add("jinzong")
// mutableListOf.remove("jonse")
// println(mutableListOf)
//List支持使用toList和toMutableList函数动态实现只读列表和可变列表的相互转换
val toMutableList = list.toMutableList()
val toList = mutableListOf.toList()
//mutator函数
//能修改可变列表的函数有个统一的名字,mutator函数,例如上面的add,remove
//添加元素运算符+=
//删除元素运算符-=
//基于lambda表达式指定的条件删除元素
mutableListOf += "jinzong"
mutableListOf -= "jonse"
println(mutableListOf)
//集合遍历
for (s in list) { //这个直接敲list.就可以找到for
println(s)
}
//与上面一样的意思
list.forEach {
println(it)
}
//带坐标
list.forEachIndexed { index, s ->
println("$index $s")
}
//解构语法过滤元素
//通过_符号过滤不想要的元素,这是之前的解构函数,如果我们不想给第二个元素赋值,直接使用_就行
val (a,b,c)= list
//过滤,相当于不给第二个元素赋值
val (a2,_,c2)= list
//set创建和元素的获取与list,区别和java的是一样的,list是有序且可以重复,set无序并且元素不能重复
val set = setOf("jack", "jacky", "jonse")
val elementAt = set.elementAt(2)//读取集合中的元素
// set.elementAtOrNull(2) 与list一样
// set.elementAtOrElse(2){"unknown"} //与list一样
println(elementAt)
//语法和list是一样的
val mutableSetOf = mutableSetOf("jack", "jacky", "jonse")
mutableListOf.add("tom")
mutableListOf.remove("jonse")
mutableListOf += "jarry"
mutableListOf -= "jack"
//集合转换与快捷函数
//需求把list中的元素去重
val list2 = listOf("jack", "jacky", "jack")
.toSet() // 去重
.toList() //再转换成list
println(list2)
//kotlin提供了一种快捷的去重函数
val list3 = listOf("jack", "jacky", "jack").distinct()
println(list3)
//数组类型
//kotlin提供各种Array,虽然是引用类型,但可以编译成java基本数据类型
/**
* 数组类型 创建函数
* IntArray intArrayOf
* DoubleArray dooubleArrayOf
* LongArray longArrayOf
* ShortArray shortArrayOf
* ByteArray byteArrayOf
* FloatArray floatArrayOf
* BooleanArray booleanArrayOf
* Array arrayOf
*/
val intArray = intArrayOf(1, 2, 3)
val toIntArray = listOf(1, 2, 3).toIntArray()
val arrayOf = arrayOf(File("xxxx"), File("xxxxxxxx"))
//map的创建
//to看上去像关键字,但事实上,它是个省略了点和参数的特殊函数,to函数将它左边和右边的值转换成一堆Pair
val map = mapOf("guo" to 20, "jin" to 21, "zhang" to 23)
// mapOf(Pair("guo",20),Pair("jin",21),Pair("zhang",23)) 和上面这句代码一个意思
println(map)
//读取map的值
/***
* []取值运算符,读取键对应的值,如果键不存在返回null
* getValue,读取键对应的值,如果不存在就抛出异常
* getOrElse,读取键对应的值,使用匿名该函数返回默认值
* getOrDefault,读取键对应的值,或者返回默认值
*/
println(map["guo"])
println(map.getValue("guo"))
println(map.getOrElse("aaa"){0})
println(map.getOrDefault("bb",1))
//map的遍历
map.forEach { (key, value) ->
println("$key $value")
}
map.forEach {
println(it.key + " " + it.value)
}
//map的可变集合
val mutableMap = mutableMapOf("guo" to 1, "jin" to 2, "zhang" to 3)
mutableMap += "li" to 4
mutableMap.put("wang",5)
//获取对应键的值,如果不存在这个键,就将这一对键值对存入;如果存在,直接取出map中对应的值
println(mutableMap.getOrPut("zheng",{7}))
println(mutableMap)
//定义一个类
class Player{
//kotlin只需要声明属性,会自动生成get和set方法。针对定义的每一个属性,kotlin都会产生一个field。
//field存储属性数据,不能自己定义field,kotlin封装field,只暴露get和set方法
var name = "jack"
//我们也可以重新定义get和set方法
get() = field.capitalize() // 返回首字母大写的字符串
set(value) {
value.trim()
}
}
//类的主构造函数,主构造函数在类名后加小括号
class Student(
//这里就是主构造函数,它的作用就是赋值给filed值,所以这里就是一个临时变量的存在,通常都会以下划线开头的名字命名
_name : String,
_age : Int,
_isNormal : Boolean
){
//每一个field重写get和set方法,需要放在其对应的下面。
var name = _name
get() = field.capitalize()
set(value) {
value.trim()
}
var age = _age
var isNormal = _isNormal
}
//kotlin允许不使用临时变量赋值,而是直接在主构造函数中定义类属性,这样可以减少代码
class Student2(
_name: String,
var age : Int,
var isNormal : Boolean
){
//每一个field重写get和set方法,需要放在其对应的下面。
var name = _name
get() = field.capitalize()
set(value) {
value.trim()
}
//次构造函数,有主就有次,我们可以定义多个次构造函数来配置不同的参数组合
constructor(_name: String) : this (_name,age = 10,isNormal = false)
//初始化块,与java的static不一样,这里的初始化块是构造函数执行的时候,就会执行初始化快
init {
//先决函数,如果boolean值是false,执行lambda抛出异常
require(age > 0) {
"age must be positive"
}
require(name.isNotBlank()){
"student must have a name"
}
}
}
/**
* 初始化顺序
* 1.先初始化主构造函数里声明的属性
* 2.类级别的属性赋值, 这里第二步和第三步的顺序调用取决于谁在上谁在下,这是个坑,分上下顺序的
* 3.init初始化块里的属性赋值和函数调用
* 4.次构造函数里的属性赋值和函数调用
* 可以在showkotlinbytecode查看调用顺序
*/
class Student3(
_name: String,
//第一步执行
var age : Int
){
//第二步执行
var name = _name
var score = 10//如果这一行写到init下面,那么init里的score*4就报错了。。。
init {
println(score*4)
//第三步执行
println("init函数执行")
}
constructor(name2:String) :this(name2,30){
score =100 //第四步执行
}
}
/**
* 延迟初始化
* 使用lateinit关键字相当于做了一个约定:在用它之前做初始化
*
*/
class Player2{
lateinit var equipment : String
fun ready(){
equipment = "ak47"
}
fun battle(){
if (::equipment.isInitialized) println(equipment)
}
}
class Player3{
//使用它时再去初始化
val config by lazy { loadConfig() }
private fun loadConfig():String{
println("loading ....")
return "xxx"
}
}