Kotlin基础语法

  • 声明变量

    复制代码
      只读         变量名          类型             参数
      val          param      :   Int        =      1
  • 内置数据类型

    ‌整数类型‌:

    Byte:8位有符号整数(-128~127)
    Short:16位有符号整数(-32,768~32,767)
    Int:32位有符号整数(-2³¹~2³¹-1)
    Long:64位有符号整数(-2⁶³~2⁶³-1),需加L后缀如123L

    ‌浮点类型‌:
    Float:32位单精度浮点数(约6-7位小数),需加F后缀如3.14F
    Double:64位双精度浮点数(约15-16位小数),默认小数类型
    ‌布尔类型‌:
    Boolean:仅含true和false两个值

    ‌字符与字符串‌:
    Char:16位Unicode字符(如'A')
    String:不可变字符序列,支持模板表达式如"Value: $x"

    复杂数据类型
    ‌数组‌:
    使用Array<T>或原生类型数组(如IntArray)
    ‌集合‌:
    不可变集合:List、Set、Map
    可变集合:MutableList、MutableSet、MutableMap

    ‌特殊类型‌:
    可空类型:通过?标记(如Int?)
    数据类:data class自动生成equals()/hashCode()等方法
    枚举类与密封类

  • Kotlin语言的只读变量

    var:可修改变动
    val:不可修改

  • 语言的类型推断

    复制代码
     // 由于Kotlin的类型推导,所以不需要特地申明类型
     val  name = xiaoming
     val age = 1
  • 编译时常量

    // 编译时常量只能是常用的基本数据类型
    // String,Double,Int,Float,Long,Short,Byte,Char,Boolean
    const val PI = 3.1415

  • range表达式

    if(value in 1..100){}

  • String模版

    val name = xiaoming
    println("name:$name")

  • 函数

    // 现有输入 再有输出
    private fun method(age: Int, name: String) : Int {
    println("你的姓名是:name,你的年龄是:age")
    return 200
    }

  • 默认参数

    fun main() {
    action01("lisi", 89)
    action02("wangwu")
    action03()
    action03("赵六", 76)
    }

    private fun action01(name: String, age: Int) {
    println("我的姓名是:name, 我的年龄是:age")
    }

    private fun action02(name: String, age: Int = 77) {
    println("我的姓名是:name, 我的年龄是:age")
    }

    private fun action03(name: String = "王五", age: Int = 67) {
    println("我的姓名是:name, 我的年龄是:age")
    }

  • 具名函数参数

    fun main() {
    loginAction(age = 99, userpwd = "123", username = "xiaoming", phonenumber = "123456")
    }

    private fun loginAction(username: String, userpwd: String, phonenumber: String, age: Int, usernam: String="") {
    println("username:username, userpwd:userpwd, phonenumber:phonenumber, age:age")
    }

  • Unit对象

    忽略类型,相当于Java的void

  • 反引号函数

    fun main() {
    `你叫什么名字("小明")
    }

    private fun 你叫什么名字(name: String) {
    println("模拟:用户名是$name)
    }

  • Nothing类型

    /**

    • public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")
    • TODO返回Nothing,Nothing类型会直接抛异常
    • /

    fun main() {
    show(99)
    }

    private fun show(number: Int) {
    when(number) {
    -1 -> TODO("没有这种分数")
    in 0..59 -> println("分数不及格")
    in 60..70 -> println("分数及格")
    in 71..100 -> println("分数优秀")
    }
    }

  • 匿名函数

    复制代码
      val len = "xiaoming".count()
      val len2 = "xiaoming".count {
          it == 'x'
      }
  • 数类型&隐式返回

    复制代码
      val methodAction : () -> String
      methodAction = {
          val inputValue = 999999
          "$inputValue  num" // == 背后隐式 return "$inputValue ";
          // 匿名函数不要写return,最后一行就是返回值
      }
  • 函数参数

    复制代码
      val methodAction : (Int, Int, Int) -> String = { number1, number2, number3 ->
          val inputValue = 999999
          "$inputValue 参数一:$number1, 参数二:$number2, 参数三:$number3"
      }
  • it关键字

    复制代码
      val methos: (String) -> String = { "$it" }
  • 函数参数调用的三种方式

    fun main() {
    // 第一种方式
    loginAPI("xiaoming", "123456", { msg: String, code:Int ->
    println("最终登录的情况如下: msg:msg, code:code")
    })

    复制代码
      // 第二种方式
      loginAPI("xiaoming", "123456", responseResult = { msg: String, code: Int ->
          println("最终登录的情况如下: msg:$msg, code:$code")
      })
    
      // 第三种方式
      loginAPI("xiaoming", "123456") { msg: String, code: Int ->
          println("最终登录的情况如下: msg:$msg, code:$code")
      }

    }

    fun loginAPI(username: String, userpwd: String, responseResult: (String, Int) -> Unit) { }

  • 内联学习

    // 此函数有使用lambda作为参数,就需要声明成内联
    // 如果此函数,不使用内联,在调用端,会生成多个对象来完成lambda的调用(会造成性能损耗)
    // 如果此函数,使用内联,相当于 C++ #define 宏定义 宏替换,会把代码替换到调用处,调用处 没有任何函数开辟 对象开辟 的损耗
    // 小结:如果函数参数有lambda,尽量使用 inline关键帧,这样内部会做优化,减少 函数开辟 对象开辟 的损耗
    inline fun loginAPI(username: String, userpwd: String, responseResult: (String, Int) -> Unit) { }

  • 函数引用

    fun methodResponseResult(msg: String, code: Int) {
    println("最终登录的成果是:msg:msg, code:code")
    }
    val obj = ::methodResponseResult

  • 函数类型作为返回类型

    fun showMethod(info: String): (String, Int) -> String {
    println("我是show函数 info:$info")

    复制代码
      // return 一个函数 匿名函数
      return { name: String, age: Int ->
          "我就是匿名函数:我的name:$name, age:$age"
      }

    }

  • 匿名函数和具名函数

    fun main() {
    // 匿名函数
    showPersonInfo("lisi", 99, '男', "学习KT语言") {
    println("显示结果:$it")
    }
    // 具名函数 showResultImpl
    showPersonInfo("wangwu", 89, '女', "学习C++语言", ::showResultImpl)
    }

    fun showResultImpl(result: String) {
    println("显示结果:$result")
    }

    inline fun showPersonInfo(name: String, age: Int, sex: Char, study: String, showResult: (String) -> Unit) {
    val str = "name:name, age:age, sex:sex, study:study"
    showResult(str)
    }

  • Kotlin语音可空性的特点

    复制代码
      //  第一种情况:默认是不可空类型,不能为null
      var name: String = "xiaoming"
      name = null  // 报错:Null cannot be a value of a non-null type 'String'.
    
      //  第二种情况:声明时指定为可空类型
      var name2: String ?
      name2 = null
  • Kotlin语言的安全操作符

    复制代码
      var name: String? = "zhangsan"
       name = null
       // name是可空类型的 可能是null,想要使用name,必须给出补救措施
        // name是可空类型的 如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
      val r = name?.capitalize() 
       // !! 断言 不管name是不是null,都执行
      val size =  name!!.size()
  • 空合并操作符

    复制代码
    var info: String? = "李小龙"
    info?.let { "【$it】" } ?: "原来你是null啊2"
  • 先决条件函数

    复制代码
    var value1: String ? = null
    var value2: Boolean = false
     // java.lang.IllegalStateException: Required value was null.
    checkNotNull(value1) 
     // java.lang.IllegalArgumentException: Required value was null.
     requireNotNull(value1) 
     // java.lang.IllegalArgumentException: Failed requirement.
      require(value2) 
  • substring

    复制代码
     val INFO = "xiaoming is Success Result"
      val indexOf = INFO.indexOf('i')
      println(INFO.substring(0, indexOf))
      println(INFO.substring(0 until indexOf)
  • 解构

    复制代码
      val jsonText = "xiaoming,xiaowang"
      val list = jsonText.split(",")
      val (v1, v2, v3, v4) = list
      println("解构四个只读变量的值是:v1:$v1, v2:$v2, v3:$v3, v4:$v4")
  • == 和 ===

    == 值 内容的比较 相当于Java的equals
    === 引用的比较

  • 字符串遍历操作

    复制代码
      val str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      str.forEach { 
          print("所有的字符是:$it  ")
      }
  • 数字类型的安全转换函数

    复制代码
      val number: Int = "666".toInt()
      val number2: Int? = "666.6".toIntOrNull()
  • Double转Int与类型格式化

    复制代码
      65.4645654.toInt())     // 65 四舍五入
      65.4645654.roundToInt()    // 65 四舍五入
      "%.3f".format(65.8343433) //格式化
  • 4大扩展函数对比

apply let run also
接收者 this it this it
返回值 对象本身 lamda表达 lamda表达 对象本身
设计思想 Build模式 转换器模式 执行器模式 观察者模式
使用场景 对象初始化 数据转换 依赖对象的数据操作 副作用操作(日志打印)
  • 内置函数with(非扩展函数)

    // 构建 HTML 内容
    val htmlContent = with(StringBuilder()) {
    append("<html>")
    append("<head><title>页面</title></head>")
    append("<body>")
    append("

    欢迎

    ")
    append("

    这是一个段落

    ")
    append("</body>")
    append("</html>")
    toString() // 返回构建的字符串
    }

    // 构建 SQL 查询
    val sql = with(StringBuilder()) {
    append("SELECT * FROM users")
    append(" WHERE age > 18")
    append(" AND status = 'active'")
    append(" ORDER BY name")
    toString()
    }

  • takeif

    复制代码
      // true: 直接返回name本身
      // false: 直接放回null

    fun checkPermissionAction2(name: String, pwd: String) : String {
    return name.takeIf { permissionSystem(name, pwd) } ?: "你的权限不够"
    }

  • takeUnless

    复制代码
      false:返回name本身,true返回null
      val r  = manager.getInfoValue().takeUnless { it.isNullOrBlank() } ?: "未经过任何初始化值"
  • mutator函数

    复制代码
    val list : MutableList<String> = mutableListOf("xiaoming", "xiaowang")
      list += "李四"
      list += "王五"
      list -= "xiaoming"
  • 集合

    // 不可变集合
    val list = listOf("A", "B", "C", "D")

    //可变集合
    val list = mutableListOf("xiaoming", "Zhangsna", "Wangwu")

  • Set

    //不可变Set
    val set: Set<String> = setOf("lisi", "wangwu", "zhaoliu", "zhaoliu") // set集合不会出现重复元素的
    //可变Set
    val set : MutableSet<String> = mutableSetOf("李元霸", "李连杰")

  • 数组

    复制代码
      Kotlin语言中的各种数组类型,虽然是引用类型,背后可以编译成Java基本数据类型
      IntArray        intArrayOf
      DoubleArray     doubleArrayOf
      LongArray       longArrayOf
      ShortArray      shortArrayOf
      ByteArray       byteArrayOf
      FloatArray      floatArrayOf
      BooleanArray    booleanArrayOf
      Array<对象类型>           arrayOf         对象数组
  • Map

    复制代码
    // 不可变Map
    val mMap1 : Map<String, Double> = mapOf<String, Double>("xiaoming" to(534.4), "Kevin" to 454.5)
    val mMap2 = mapOf(Pair("xiaoming", 545.4), Pair("Kevin", 664.4))

    // 可变Map
    val map : MutableMap<String, Int> = mutableMapOf(Pair("xiaoming", 123), "Kevin" to 456, Pair("xiaowang", 789))

  • field关键字

    复制代码
      var name = "xiaoming"
          get() = field
          set(value) {
              field = value
          }
  • 计算属性 与 防范竞态条件

    复制代码
      val number2 : Int
          get() = (1..1000).shuffled().first() // 从1到1000取出随机值 返回给 getNumber2()函数
      /*
          背后隐式代码:
    
          为什么没有看到 number2 属性定义?
          答:因为属于 计算属性 的功能,根本在getNumber2函数里面,就没有用到 number2属性,所以 number2属性 失效了,无用了,以后用不到了
    
           public int getNumber2() {
              return (1..1000).shuffled().first()java的随机逻辑 复杂 ;
         }
       */
    
      var info: String ? = null // ""
    
      // 防范竞态条件  当你调用成员,这个成员,可能为null,可能为空值,就必须采用 防范竞态条件,这个是KT编程的规范化
      fun getShowInfo() : String {
    
          // 这个成员,可能为null,可能为空值,就启用 防范竞态条件
          // 这种写法,就属于 防范竞态条件,我们可以看到专业的KT开发者,有大量这种代码
          // also永远都是返回 info本身
          return info?.let {
              if (it.isBlank()) {
                  "info你原来是空值,请检查代码..." // 是根据匿名函数最后一行的变化而变化
              } else {
                  "最终info结果是:$it" // 是根据匿名函数最后一行的变化而变化
              }
          } ?: "info你原来是null,请检查代码..."
      }
  • 主构造函数

    class KtBase72(_name: String, _sex: Char, _age: Int, _info: String) {}

  • 主构造函数里定义属性

    // var name: String 就相当于 var name = _name 这不过你看不到而已
    // 一步到位,不像我们上一篇是分开写的
    class KtBase73 (var name: String, val sex: Char, val age: Int, var info: String)
    {
    fun show() {
    println(name)
    println(sex)
    println(age)
    println(info)
    }
    }

  • 次构造函数

    class KtBase74(name: String) // 主构造
    {
    // 2个参数的次构造函数,必须要调用主构造函数,否则不通过, 为什么次构造必须调用主构造?答:主构造统一管理 为了更好的初始化设计
    constructor(name: String, sex: Char) : this(name) {
    println("2个参数的次构造函数 name:name, sex:sex")
    }

    复制代码
      // 3个参数的次构造函数,必须要调用主构造函数
      constructor(name: String, sex: Char, age: Int) : this(name) {
          println("3个参数的次构造函数 name:$name, sex:$sex, age:$age")
      }
    
      // 4个参数的次构造函数,必须要调用主构造函数
      constructor(name: String, sex: Char, age: Int, info: String) : this(name) {
          println("4个参数的次构造函数 name:$name, sex:$sex, age:$age, info:$info")
      }

    }

  • 构造函数中默认参数

    class KtBase75(name: String = "李元霸") // 主构造
    {
    // 2个参数的次构造函数,必须要调用主构造函数
    constructor(name: String = "李连杰", sex: Char = 'M') : this(name) {
    println("2个参数的次构造函数 name:name, sex:sex")
    }

    复制代码
      // 3个参数的次构造函数,必须要调用主构造函数
      constructor(name: String = "李小龙", sex: Char = 'M', age: Int = 33) : this(name) {
          println("3个参数的次构造函数 name:$name, sex:$sex, age:$age")
      }
    
      // 4个参数的次构造函数,必须要调用主构造函数
      constructor(name: String = "李俊", sex: Char = 'W', age: Int = 87, info: String = "还在学校新开发语言") : this(name) {
          println("4个参数的次构造函数 name:$name, sex:$sex, age:$age, info:$info")
      }

    }

    fun main() {
    val p = KtBase75("李元霸2") // 调用主构造

    复制代码
      KtBase75("张三", '男') // 调用 2个参数的次构造函数
    
      KtBase75("张三2", '男', 88) // 调用 3个参数的次构造函数
    
      KtBase75("张三3", '男', 78, "还在学校新语言") // 调用 4个参数的次构造函数
    
      KtBase75() // 到底是调用哪一个 构造函数,是次构造 还是 主构造 ? 答:优先调用主构造函数

    }

  • 初始化块

    class KtBase76 (username: String, userage: Int, usersex: Char) // 主构造
    {
    // 这个不是Java的 static{}
    // 相当于是Java的 {} 构造代码块
    // 初始化块 init代码块
    // 临时类型只有在 init代码块才能调用
    init {
    println("主构造函数被调用了 username, userage, $usersex")
    // 如果第一个参数是false,就会调用第二个参数的lambda
    // 判断name是不是空值 isNotBlank ""
    require(username.isNotBlank()) { "你的username空空如也,异常抛出" }
    require(userage > 0) { "你的userage年龄不符合,异常抛出" }
    require( usersex == '男' || usersex == '女') { "你的性别很奇怪了,异常抛出" }
    }

    复制代码
      constructor(username: String) : this(username, 87, '男') {
          println("次构造函数被调用了")
      }
    
      fun show() {
          // println(username) // 用不了,必须要二次转换,才能用
      }

    }

  • lateinit

    复制代码
      lateinit var responseResultInfo: String // 我等会儿再来初始化你,我先定义再说,所以没有赋值
    
      // 模拟服务器加载
      fun loadRequest() { // 延时初始化,属于懒加载,用到你在给你加载
          responseResultInfo = "服务器加载成功,恭喜你"
      }
    
      fun showResponseResult() {
          // 由于你没有给他初始化,所以只要用到它,就奔溃
          // if (responseResultInfo == null) println()
          // println("responseResultInfo:$responseResultInfo")
    
          if (::responseResultInfo.isInitialized) {
              println("responseResultInfo:$responseResultInfo")
          } else {
              println("你都没有初始化加载,你是不是忘记加载了")
          }
      }
  • by lazy

    val databaseData2 by lazy { readSQlServerDatabaseAction() }

  • 初始化陷阱

    Kotlin 初始化有执行顺序问题,涉及到的属性要放在被访问函数的上面,包括init{}

  • 继承与重载的open关键字学习

    open class Person(private val name: String) {
    private fun showName() = "父类 的姓名是【$name】"
    open fun myPrintln() = println(showName())
    }

  • 类型转换

    复制代码
      if (p is Student2) {
          (p as Student2).myPrintln()
      }
  • Any超类

    在KT中,所有的类,都隐士继承了 : Any() ,你不写,默认就有
    Any类在KT设计中:只提供标准,你看不到实现,实现在各个平台处理好了

  • 单例类申明

    object data{}

  • 对象表达式

    复制代码
      val p : KtBase88 = object : KtBase88() {
    
          override fun add(info: String) {
              // super.add(info)
              println("我是匿名对象 add:$info")
          }
    
          override fun del(info: String) {
              // super.del(info)
              println("我是匿名对象 del:$info")
          }
      }
  • 伴生对象

    //伴生对象的由来: 在KT中是没有Java的这种static静态,
    //伴生很大程度上和Java的这种static静态
    class KtBase89 {
    companion object {
    val info = "DerryINfo"
    fun showInfo() = println("显示:$info")
    val name = "Derry"
    }
    }

  • 内部类

    // 内部类的特点: 内部的类 能访问 外部的类
    // 外部的类 能访问 内部的类
    inner class Heart { // 心脏类
    fun run() = println("心脏访问身体信息:$bodyInfo")
    }

  • 嵌套类

    // 嵌套类特点:外部的类 能访问 内部的嵌套类
    // 内部的类 不能访问 外部类的成员
    class Outer {
    val info: String = "OK"
    fun show() {
    Nested().output()
    }
    class Nested {
    fun output() = println("嵌套类")
    }
    }

  • 数据类

    data class

  • copy函数

    复制代码
      val p1 = KtBase92("李元霸") // 调用次构造初始化对象
      println(p1)
      val newP2 = p1.copy("李连杰", 78)
      println(newP2)
      // copy toString hashCode equals 等等... 主管主构造,不管次构造
      // 注意事项:使用copy的时候,由于内部代码只处理主构造,所以必须考虑次构造的内容
  • 解析函数

    // 传统方式
    val student = Student1("李四", 89, '男')
    val name = student.name
    val age = student.age
    val sex = student.sex

    // 解构方式 - 更简洁
    val (name, age, sex) = Student1("李四", 89, '男')

  • 密封类

    // 条件一:服务器请求回来的响应的 JavaBean LoginResponseBean 基本上可以使用 数据类
    // 条件二:数据类至少必须有一个参数的主构造函数
    // 条件三:数据类必须有参数, var val 的参数
    // 条件四:数据类不能使用 abstract,open,sealed,inner 等等 修饰 (数据类,数据载入的事情 数据存储)
    // 条件五:需求 比较,copy,toString,解构,等等 这些丰富的功能时,也可以使用数据类
    // 密封类,我们成员, 就必须有类型 并且 继承本类
    sealed class Exams {
    // object? Fraction1 Fraction3 都不需要任何成员,所以一般都写成object,单例就单例,无所谓了
    object Fraction1 : Exams() // 分数差
    object Fraction2 : Exams() // 分数及格
    object Fraction3 : Exams() // 分数良好

    复制代码
      // 假设 Fraction4 是可以写object的,那么也不合理,因为对象不是单例的,有 对象1李四 对象2王五
      class Fraction4(val studentName : String) : Exams() // 分数优秀
    
      // 需求 得到优秀的孩子姓名
      // var studentName: String? = null
      // 我们用枚举类,要做到此需求,就非常的麻烦了,很难做到而已,不是做不到
      //  需求:引出 密封类

    }

  • 接口的默认实现

    interface USB2 {

    复制代码
      // 1.接口 var 也是不能给接口的成员赋值的 (但是有其他办法)
      // 2.任何类 接口 等等  val 代表只读的,是不可以在后面动态赋值 (也有其他办法)
    
      val usbVersionInfo: String // USB版本相关的信息
         get() = (1..100).shuffled().last().toString()
         // val 不需要set
    
      val usbInsertDevice: String // USB插入的设备信息
          get() = "高级设备接入USB"
          // val 不需要set
    
      fun insertUBS() : String

    }

    class Mouse2 : USB2 {

    复制代码
      override val usbInsertDevice: String
          get() = super.usbInsertDevice
    
      override val usbVersionInfo: String
          get() = super.usbVersionInfo
    
      override fun insertUBS() = "Mouse $usbVersionInfo, $usbInsertDevice"

    }

  • 抽象类

    abstract class BaseActivity {
    fun onCreate() {
    setContentView(getLayoutID())
    initView()
    initData()
    initXXX()
    }
    private fun setContentView(layoutID: Int) = println("加载{$layoutID}布局xml中")
    abstract fun getLayoutID(): Int
    abstract fun initView()
    abstract fun initData()
    abstract fun initXXX()
    }

    class MainActivity : BaseActivity() {
    override fun getLayoutID(): Int = 564
    override fun initView() = println("做具体初始化View的实现")
    override fun initData() = println("做具体初始化数据的实现")
    override fun initXXX() = println("做具体初始化XXX的实现")
    fun show() {
    super.onCreate()
    }
    }

  • 扩展函数

    fun String.showStr() = println(this)

  • 可空类型扩展函数

    fun String?.outputStringValueFun(defalutValue : String) = println(this ?: defalutValue)

  • infix关键字

    private infix fun <C1, C2> C1.gogogo(c2: C2) {
    }
    fun main() {
    mapOf("零".to(0))
    123 gogogo '男'
    }

  • 重命名扩展

    fun <E> Iterable<E>.randomItemValue() = this.shuffled().first()
    fun <T> Iterable<T>.randomItemValuePrintln() = println(this.shuffled().first())

    import com.derry.s6.com.derry.randomItemValue as g // as g 重命名扩展操作
    import com.derry.s6.com.derry.randomItemValuePrintln as p // as g 重命名扩展操作
    fun main() {
    val list : List<String> = listOf("李元霸", "李连杰", "李小龙")
    val set : Set<Double> = setOf(545.5, 434.5, 656.6)
    println(list.g())
    println(set.g())
    list.p()
    set.p()
    }

  • 变换函数-map

    复制代码
    val list = listOf("李元霸", "李连杰", "李小龙")

    val list3 : List<String> = list.map {
    "姓名是:it" }.map { "it,文字的长度是:{it.length}" }.map { "【it】"
    }
    for (s in list3) {
    print("$s ")
    }

    【姓名是:李元霸,文字的长度是:7】 【姓名是:李连杰,文字的长度是:7】 【姓名是:李小龙,文字的长度是:7】

  • 变换函数-flatMap

    复制代码
       [你的姓名是:李四, 你文字的长度是:8 在学习C++,
       你的姓名是:李四, 你文字的长度是:8 在学习Java,
       你的姓名是:李四, 你文字的长度是:8 在学习Kotlin,
    
       你的姓名是:王五, 你文字的长度是:8 在学习C++,
       你的姓名是:王五, 你文字的长度是:8 在学习Java,
       你的姓名是:王五, 你文字的长度是:8 在学习Kotlin,
    
       你的姓名是:赵六, 你文字的长度是:8 在学习C++,
       你的姓名是:赵六, 你文字的长度是:8 在学习Java,
       你的姓名是:赵六, 你文字的长度是:8 在学习Kotlin,
    
       你的姓名是:初七, 你文字的长度是:8 在学习C++,
       你的姓名是:初七, 你文字的长度是:8 在学习Java,
       你的姓名是:初七, 你文字的长度是:8 在学习Kotlin]
       
      val newList : List<String> = list.map {
          "你的姓名是:$it" // 每次返回一个 String
      }.map {
          "$it, 你文字的长度是:${it.length}" // 每次返回一个 String
      }.flatMap {
          listOf("$it 在学习C++", "$it 在学习Java", "$it 在学习Kotlin") // 每次返回一个集合,四次
      }
      println(newList)
  • 过滤函数-filter

    复制代码
      val list : List<String> = listOf("李四", "王五", "赵六", "初七")
      val newList : List<String> = list.map {
          "你的姓名是:$it" // 每次返回一个 String
      }.map {
          "$it, 你文字的长度是:${it.length}" // 每次返回一个 String
      }.flatMap {
          listOf("$it 在学习C++", "$it 在学习Java", "$it 在学习Kotlin")
      }.filter {
          it != "李四"
      }
       [ 你的姓名是:王五, 你文字的长度是:8 在学习C++,
       你的姓名是:王五, 你文字的长度是:8 在学习Java,
       你的姓名是:王五, 你文字的长度是:8 在学习Kotlin,
    
       你的姓名是:赵六, 你文字的长度是:8 在学习C++,
       你的姓名是:赵六, 你文字的长度是:8 在学习Java,
       你的姓名是:赵六, 你文字的长度是:8 在学习Kotlin,
    
       你的姓名是:初七, 你文字的长度是:8 在学习C++,
       你的姓名是:初七, 你文字的长度是:8 在学习Java,
       你的姓名是:初七, 你文字的长度是:8 在学习Kotlin]
  • 合并函数-zip

    复制代码
      val names = listOf("张三", "李四", "王五")
      val ages = listOf(20, 21, 22)
      val zip : List<Pair<String, Int>> = names.zip(ages)
      println(zip)
      
      [(张三, 20), (李四, 21), (王五, 22)]
  • 饿汉式

    object SingletonDemoKt

  • 懒汉式

    class SingletonDemo4Kt private constructor() {

    复制代码
      companion object {
          val instance : SingletonDemo4Kt by lazy (mode = LazyThreadSafetyMode.SYNCHRONIZED) { SingletonDemo4Kt() }
      }

    }

  • @JvmField @JvmStatic 静态注解

相关推荐
九皇叔叔4 小时前
Linux Shell 正则表达式中的 POSIX 字符集:用法与实战
linux·运维·正则表达式
東雪蓮☆5 小时前
K8s 平滑升级
linux·运维·云原生·kubernetes
---学无止境---6 小时前
Linux中进程创建和缓存对象初始化fork_init、proc_caches_init和buffer_init
linux
qq_183802876 小时前
Linux内核idr数据结构使用
linux·运维·服务器
噜啦噜啦嘞好6 小时前
Linux:库制作与原理
linux·运维·服务器
---学无止境---6 小时前
Linux中将EFI从物理模式切换到虚拟模式efi_enter_virtual_mode函数的实现
linux
刘某的Cloud7 小时前
磁盘-IO
linux·运维·系统·磁盘io
我狸才不是赔钱货8 小时前
容器:软件世界的标准集装箱
linux·运维·c++·docker·容器
云知谷8 小时前
【嵌入式基本功】单片机嵌入式学习路线
linux·c语言·c++·单片机·嵌入式硬件