集合 List List.kt
List创建与元素获取
1 2 3 4 val list = listOf("girl1" , "girl2" , "girl3" )println(list.getOrElse(3 ) { "Unknown" }) println(list.getOrNull(3 )) println(list.getOrNull(3 ) ?: "Unknown" )
可变列表
1 2 3 4 5 6 7 val mutableList = mutableListOf("Jason" , "Jack" , "girl1" )mutableList.add("Jimmy" ) mutableList.remove("Jack" ) println(mutableList) list.toMutableList() mutableList.toList()
mutator函数
1 2 3 4 mutableList += "John" mutableList -= "girl1" mutableList.removeIf{it.contains("Jack" )} println(mutableList)
集合遍历
for in
forEach
forEachIndexed遍历时要获取索引
1 2 3 4 5 6 7 8 9 for (s in list){ println(s) } list.forEach{ println(it) } list.forEachIndexed{index,item-> println("$index $item " ) }
解构 通过_符号过滤不想要的元素
1 2 val (girl1,_,girl3) = list
Set集合 elementAt获取元素 1 2 3 4 5 val set = setOf("girl1" , "girl2" , "girl3" , "girl1" )println(set .elementAt(2 )) val mutableSet = mutableSetOf("girl1" , "girl2" , "girl3" , "girl1" )mutableSet += "girl5"
List去重 通过toSet去重
1 2 3 4 5 val list = mutableSetOf("girl1" , "girl2" , "girl3" , "girl1" ).toSet().toList()println(list) val distinct = mutableSetOf("girl1" , "girl2" , "girl3" , "girl1" ).distinct()println(distinct)
数组类型 kotlin提供了各种Array,虽然是引用类型,但最终编译成Java基本数据类型
1 2 3 val intArray = intArrayOf(10 , 30 , 40 )listOf(10 , 30 , 40 ).toIntArray() val array = arrayOf(File("xxx" ), File("yyyy" ))
Map集合
map获取 1 2 3 4 println(map["lucy1" ]) println(map.getValue("lucy2" )) println(map.getOrElse("Jon" ){"Unknown" }) println(map.getOrDefault("Jon" ,0 ))
map遍历 1 2 3 4 5 6 map.forEach{ println("${it.key} , ${it.value} " ) } map.forEach{(key:String,value:Int )-> println("${key} , ${value} " ) }
mutableMap 1 2 3 4 5 val mutableMap = mutableMapOf("lucy1" to 18 , "lucy2" to 19 , "lucy3" to 20 )mutableMap += "jon" to 22 mutableMap.put("jon2" ,35 ) mutableMap.getOrPut("Rose" ){30 } println(mutableMap)
定义类
1 2 3 4 5 6 7 8 Class Player{ var name:String? = "jack" } fun main () { var p = Player() p.name = "rose" }
计算属性 1 2 3 4 5 6 7 8 9 10 11 12 13 class Player { var name: String = "jack" get () = field.capitalize() set (value) { field = value.trim() } val rolledValue get () = (1. .6 ).shuffled().first() }
防范竞态条件 1 2 3 4 5 6 7 var words:String? = "hello" fun saySomething () { words?.also { println("Hello ${it.uppercase()} " ) } }
构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Student ( _name: String, _age: Int , _isNormal: Boolean ) { var name = _name get () = field.capitalize() private set (value) { value.trim() } var age = _age get () = age.absoluteValue set (value) { field = value.absoluteValue } var isNormal = _isNormal } fun main () { val p = Student("john" , 19 , true ) }
主构造函数里定义属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Student2 ( _name: String, val age: Int , val isNormal: Boolean ) { var name = _name get () = field.capitalize() private set (value) { value.trim() } } fun main () { val p = Student2("john" , 19 , true ) }
次构造函数 Student2.kt
1 2 3 4 5 6 7 8 9 constructor (_name:String):this (_name,age=100 ,isNormal = false )constructor (_name:String,age: Int ):this (_name,age=100 ,isNormal = false ){ this .name = name.uppercase() } fun main () { val p2 = Student2("Rose" ) val p3 = Student2("Rose" ,20 ) }
构造函数给默认值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Student3 ( _name: String, val age: Int = 20 , val isNormal: Boolean ) { var name = _name get () = field.capitalize() private set (value) { value.trim() } } fun main () { Student3(isNormal = false , _name = "Jon" ) }
初始化块 初始化块可以设置变量或值,以及执行有效性检查,如果检查传给某构造函数的值是否有效,初始化块代码会在构造类实例时执行 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Student3 ( _name: String, val age: Int = 20 , val isNormal: Boolean ) { var name = _name get () = field.capitalize() private set (value) { value.trim() } init { require(age>0 ){"age must be positive" } require(name.isNotBlank()){"player must have a name." } } } fun main () { Student3(isNormal = false , _name = "Jon" ) Student3(isNormal = false , _name = "" ) }
初始化顺序
主构造函数里声明的属性
类级别的属性赋值
Init初始化块里的属性赋值和函数调用
次构造函数里的属性赋值和函数调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Student4 ( _name: String, val age: Int ){ var name = _name var score = 10 ; private val hobby = "music" val subject:String init { println("initializing student" ) subject = "english" } constructor (_name: String):this (_name,10 ){ score = 20 } } fun main () { Student4("jon" ) }
反编译字节码后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public Student4 (@NotNull String _name, int age) { Intrinsics.checkNotNullParameter(_name, "_name" ); super (); this .age = age; this .name = _name; this .score = 10 ; this .hobby = "music" ; String var3 = "initializing student" ; boolean var4 = false ; System.out.println(var3); this .subject = "english" ; } public Student4 (@NotNull String _name) { Intrinsics.checkNotNullParameter(_name, "_name" ); this (_name, 10 ); this .score = 20 ; }
延迟初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Player4 { lateinit var equipment:String fun ready () { equipment = "sharp knife" } fun battle () { if (::equipment.isInitialized) println(equipment) } } fun main () { val p = Player4() p.ready() p.battle() }
惰性初始化 延迟初始化并不是推后初始化的唯一方式,也可以暂时不初始化某个变量,直到首次使用它才初始化 ,这个叫做惰性初始化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Player5 (_name: String) { var name = _name val config by lazy { loadConfig() } private fun loadConfig () : String { println("loading..." ) return "beauty girl" } } fun main () { val p = Player5("girl" ) Thread.sleep(5000 ) println(p.config) }
Java不会有这种陷阱
初始化陷阱1 顺序非常重要,必须保证块中的所有属性已完成初始化
1 2 3 4 init { val bloodBonus = blood.times(4 ) } val blood = 100
初始化陷阱2 1 2 3 4 5 6 7 8 9 10 11 12 class Player7 { val name:String private fun firstLetter () = name[0 ] init { println(firstLetter()) name= "john" } } fun main () { Player7() }
初始化陷阱3 initPlayerName() 初始化 playerName时,name属性还未完初始化。
1 2 3 4 5 6 7 8 9 class InitTrapTest3 (_name:String) { val playerName:String = initPlayerName() val name:String = _name private fun initPlayerName () = name } fun main () { println(InitTrapTest3("John" ).playerName) }