自学kotlin笔记

1.只读变量和可修改变量

        val:只读变量
        var:可修改变量

        编译时常量,必须在编译时赋值,在函数之外声明(const val MAX = 200)     (函数都是在运行时调用,所以函数内的变量是在运行时赋值的)
编译时常量只能是常见的基本数据类型:String Int Double Float Long Short Byte Char Boolean
        查看Kotlin编译之后的字节码:
        1.shift*2
        2.Tools->Kotlin->Show Kotlin Bytecode

2.表达式

if-else:

val a = if(boolean类型) “true” else “false”

when:

val school = "小学"
val level: Any = when (school) {
    "学前班" -> "幼儿"
    "小学" -> "少儿"
    "中学" -> "青少年"
    else -> {
        println("未知")
    }
}

range:

1..24:1<=x<=24

3. 具名函数

    //使用:fix(age=10,name="Rose"),不用管参数顺序
    //参数可以给默认值
    //具名函数要写return语句
    fun fix(name: String, age: Int = 2) {
        println(name + age)
    }

4.Unit类型和Nothing类型

Unit:无返回值
Nothing:如TODO函数的任务就是抛出异常,永远不能运行成功,返回Nothing类型

5.匿名函数(lambda表达式)

    val total = "Mississippi".count()

    //如果一个函数的lambda参数排在最后,或者是唯一的参数,
    //那么括住lambda值参的一对圆括号就可以省略
    val total1 = "Mississippi".count { letter ->
        letter == 's'
    }
    /*val total1 = "Mississippi".count ({ letter ->
        letter == 's'
    })*/

    val total2 = "Mississippi".count {
        it == 's'
    }

    //method变量的类型是(String) -> String
    //匿名函数不需要return,自动返回函数体最后一行结果
    //无参匿名函数(: () -> String可省略,自动推断类型)
    var method: () -> String = {
        val holiday = "Vlentine's Day."
        "Happy $holiday !"
    }

    //有参匿名函数(参数是name,String类型,返回值String类型 )
    //调用method1("Jack")
    var method1: (String) -> String = { name ->
        val holiday = "Valentine's Day."
        "$name , Happy $holiday !"
    }

    //有参匿名函数(匿名函数只有一个参数时,可以用it关键字代替参数 )
    var method2: (String) -> String = {
        val holiday = "Valentine's Day."
        "$it , Happy $holiday !"
    }

    //不使用类型推断
    var method3: (String, Int) -> String = { name, year ->
        val holiday = "Valentine's Day."
        "$name , Happy $holiday $year!"
    }

    //使用类型推断
    var method4 = { name: String, year: Int ->
        val holiday = "Valentine's Day."
        "$name , Happy $holiday $year!"
    }

 6.一个函数作为另外一个函数的参数

    fun main(){
        //获取促销文案
        /*val getDiscountWords = {goodsName:String,hour:Int ->
            val currentYear = 2027
            //$变量名后要加空格,或者用大括号括起来
            "$currentYear 年,双11$goodsName 促销倒计时: ${hour}小时"
        }
        //展现,传入goodsName和getDiscountWords变量,执行showOnBoard,此处只是将变量传入
        showOnBoard("卫生纸",getDiscountWords)*/

        //以上调用showOnBoard函数的省略写法
        showOnBoard("卫生纸"){goodsName:String,hour:Int ->
            val currentYear = 2027
            //$变量名后要加空格,或者用大括号括起来
            "${currentYear}年,双11$goodsName 促销倒计时:${hour}小时"
        }
    }

    //使用内联函数,提高使用lambda表达式后程序的性能,但使用lambda的递归函数无法内联,会导致无限循环
    inline fun showOnBoard(goodsName:String,getDiscountWords:(String,Int) -> String){
        //shuffled打乱顺序取last最后一个值
        val hour = (1..24).shuffled().last()
        //在这里相当于真正调用getDiscountWords函数
        println(getDiscountWords(goodsName,hour))
    }

 函数的参数列表中除了可以传lambda,还可以传具名函数

    fun main(){    
        //要获得函数引用,使用::操作符,后面跟要引用的函数名    
        showOnBoard("卫生纸",::getDiscountWords)
    }

    fun showOnBoard(goodsName:String,getDiscountWords:(String,Int) -> String){
        //shuffled打乱顺序取last最后一个值
        val hour = (1..24).shuffled().last()
        //在这里相当于真正调用getDiscountWords函数
        println(getDiscountWords(goodsName,hour))
    }

    fun getDiscountWords(goodsName:String,hour:Int): String {
        val currentYear = 2027
        //$变量名后要加空格,或者用大括号括起来
        return "${currentYear}年,双11$goodsName 促销倒计时:${hour}小时"
    }

7.返回类型是函数类型

    fun main(){   
        val getDiscountWords = configDiscountWords()
        println(getDiscountWords("syf"))
    }

    //返回类型是函数类型,configDiscountWords不需要传参,返回函数需要传String类型的参数
    fun configDiscountWords(): (String) -> String {
        return { it ->
            "$it"
        }
    }

8.闭包

return后的lambda表达式可以引用它作用域外的变量age和sex

    fun main(){   
        val getDiscountWords = configDiscountWords()
        println(getDiscountWords("syf"))
    }

    fun configDiscountWords(): (String) -> String {
        val age = 22
        val sex = "女"
        return { it ->
            "姓名:$it,性别:$sex,年龄:$age........."
        }
    }

 作用域呈现出以下状态:

java实现:

    public static void main(String[] args){
        showOnBoard("牙膏", new DiscountWords() {
                @Override
                public String getDiscountWords(String goodsName, int hour) {
                    return "2027年,双11" + goodsName + "促销倒计时:" + hour + "小时";
                }
            });
    }

    public interface DiscountWords {
        String getDiscountWords(String goodsName, int hour);
    }

    public static void showOnBoard(String goodsName, DiscountWords discountWords) {
        int hour = new Random().nextInt(24);
        System.out.println(discountWords.getDiscountWords(goodsName, hour));
    }

 9.可空性(变量默认为非空)

?:代表可空

?.:安全调用操作符,可空时使用

!!.:非空断言操作符,当变量值为null时,会抛出KotlinNullPointerException

        var str:String? = "butterfly"
        str = null
        println(str?.capitalize())//会输出null
        var str:String? = "butterfly"
        str = ""
        str = str?.let{
            if(it.isNotBlank()){
                it.capitalize()//输出Butterfly
            }else{
                "butterfly"
            }
        }
        println(str)

let标准函数返回的是匿名函数(lambda表达式)最后一行执行的结果 

        var str: String? = "butterfly"
        str = null
        println(str!!.capitalize())//str为空会报KotlinNullPointException
//如果str为空,则输出jack,否则输出str    
println(str ?: "jack")
//如果str为空,则为jack,否则为str并首字母大写
str = str?.let { it.capitalize() } ?: "jack"

10. 自定义异常

    onCreate:
        var number:Int? = 0
        try {
            checkOperation(number)
            number = number!!.plus(3)
            println(number)
        }catch (e:Exception){
            println(e)
        }


    fun checkOperation(number: Int?){
        number ?: throw UnskilledException()
    }

    class UnskilledException:IllegalArgumentException("操作不当")

以上代码输出3,如果number为空,输出:com.example.kotlintest.MainActivity$UnskilledException: 操作不当

11.字符串操作

        //substring
        val name = "Jimmy's friend"
        val index = name.indexOf('\'')
//        val str = name.substring(0,index)
        val str = name.substring(0 until index)
        println(str)

        //split
        val names = "Jack,Sunny,Jimmy,xiexie"
        val (a,b,c,d) = names.split(',')//split返回值是list,给多个变量赋值
        println("$a $b $c $d")

        //replace
        val strings = "I am so poor that i can not afford a cake!"
        val str2 = strings.replace(Regex("[aeiou]")){//正则表达式Regex
            when(it.value){
                "a" -> "8"
                "e" -> "6"
                "i" -> "4"
                "o" -> "2"
                "u" -> "0"
                else -> it.value
            }
        }
        println("strings:$strings,str2:$str2")

12.字符串比较:(==:字符是否匹配,===:检查两个变量是否只想内存堆上同一对象)

        val str3 = "Jason"
        val str4 = "Jason"
        println(str3 == str4)//true
        println(str3 === str4)//true

        val str3 = "Jason"
        val str4 = "jason".capitalize()
        println(str3 == str4)//true
        println(str3 === str4)//false

 13.字符串遍历

        "I am so poor that i can not afford a cake!".forEach {
            print("$it *")//打印不出来,只能通过logcat显示:This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
            Log.d("syf","$it *")
        }

 14.数字类型的安全转换函数

        //抛出异常,转换失败
        //val num: Int = "8.98".toInt()
        val num:Int? = "8.98".toIntOrNull()
        println(num)

 15.Double转Int和类型格式化

        println(8.956756.toInt())
        println(8.956756.roundToInt())
        val s = "%.2f".format(8.956756)
        println(s)

16.标准库函数 

apply: 可以看做一个配置函数,可以传入一个接受者,然后调用一系列函数来配置它以便使用,他会返回配置好的接受者

        val file1 = File("E://i have a dream_copy.txt")
        file1.setReadable(true)
        file1.setWritable(true)
        file1.setExecutable(false)

        val file2: File = File("E://i have s dream_copy.txt").apply {
            setReadable(true)
            setWritable(true)
            setExecutable(false)
        }

 let:会把接受者穿给lambda,而apply什么都不传,匿名函数执行完,let会返回lambda的最后一行

        val result = listOf(3, 2, 1).first().let {
            it * it
        }
        println(result)

        //调用
        println(formatGreeting("Jack"))
        println(formatGreeting(null))

    fun formatGreeting(guestName: String?): String {
        return guestName?.let {
            "Welcome,$it."
        } ?: "What's your name?"
    }

 run:光看作用域行为,run和apply差不多,但与apply不同,run函数不返回接受者,run返回的是lambda结果。

读取文件:

        val file = File("E://i have a dream_copy.txt")
        val result = file.run {
            readText().contains("great")//读取文件
        }
        println(result)

 判断是否过长:

        //::调用函数
        val result = "The people's Republic of China.".run(::isLong)
        println(result)
    }

    fun isLong(name: String) = name.length >= 10

 体现优势:

        //::调用函数
        "The people's Republic of China."
            .run(::isLong)
            .run(::showMessage)
            .run(::println)
    }

    fun isLong(name: String) = name.length >= 10

    fun showMessage(isLong:Boolean):String{
        return if(isLong){
            "Name is too long."
        }else{
            "Please rename."
        }
    }

 with:run的变体,但with的调用方式不同,调用with时需要值参作为其第一个参数传入

with和run的区别:

        val result1 = "The people's Republic of China.".run {
            length >= 10
        }
        val result2 = with("The people's Republic of China.") {
            length >= 10
        }

also:和let一样,also也是把接受者作为值参传给lambda,但是also返回接受者对象,而let返回lambda结果,所以also尤其适合针对同一原始对象

        var fileContents:List<String>
        File("E://i have a dream_copy.txt")
            .also {
                println(it.name)
            }.also {
                fileContents = it.readLines()
            }

        println(fileContents)

 takeIf:

        val result = File("C://i have a dream_copy.txt")
            .takeIf { it.exists() && it.canRead() }
            ?.readText()

        println(result)

takeUnless:

        val result = File("C://i have a dream_copy.txt")
            .takeUnless { it.isHidden }
            ?.readText()

filter: 筛选满足lambda最后一行的元素并返回

17.集合

        val list = listOf("Jason","Jack","Jacky")
        println(list.getOrElse(4){"Unknown"})
        println(list.getOrNull(4))
        println(list.getOrNull(4) ?: "Unknown")

 可变集合:

        val mutableListOf = mutableListOf("Jason", "Jack", "Jacky")
        mutableListOf.add("Jimmy")
        mutableListOf.remove("Jack")
        println(mutableListOf)

        //可变与不可变list互转
        listOf("Jason","Jack","Jacky").toMutableList()
        mutableListOf("Jason", "Jack", "Jacky").toList()

可变集合的遍历:

        val list = mutableListOf("Jason", "Jack", "Jacky")
        list.add("Jimmy")
        list.remove("Jack")
        for(s in list){
            println(s)
        }

        list.forEach{
            println(it)
        }

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

 mutator函数的使用:

        val mutableListOf = mutableListOf("Jacky", "Jack", "Jimmy")
//        mutableListOf.add("Jerry")
//        mutableListOf.remove("Jack")

        //新增函数
        mutableListOf += "Rose"
        //删除函数
        mutableListOf -= "Jacky"
        //使用lambda表达式删除元素
        //先在lambda判断元素是否存在,当元素存在返回true,则删除元素
        mutableListOf.removeIf {
            it.contains("Jack")
        }

        for (s in mutableListOf) {
            println(s)
        }

 解构语法过滤元素:

        //不想给变量赋值,过滤元素,用_代替
        val (origin,_,proxy) = mutableListOf

 Set创建与元素获取:

        val setList = setOf("Kotlin", "Java", "Scale","Java")
        println(setList.elementAt(2))

        val mutableSetOf = mutableSetOf("Kotlin", "Java", "Scale", "Java")
        mutableSetOf += "C++"

集合转换和快捷函数:

        val list = listOf("Kotlin", "Java", "Scale", "Java")
            .toSet()
            .toList()
        println(list)

        println(listOf("Kotlin", "Java", "Scale", "Java")
            .distinct())

 数组集合:

        val intArray = intArrayOf(10,30,40)
        listOf(10,30,40).toIntArray()
        //file数组
        val arrayOf = arrayOf(File("xxx"), File("yyyy"))

Map集合:

        //创建map的两种方式
        val mapOf1 = mapOf("Jack" to 20, "Jason" to 18, "Jack" to 30)
        val mapOf2 = mapOf(Pair("Jimmy", 20), Pair("Jacky", 20))
        //读取map的值
        println(mapOf1["Jack"])
        println(mapOf1.getValue("Jack"))
        println(mapOf1.getOrElse("Rose") { "Unknown" })
        println(mapOf1.getOrDefault("Rose", 0))
        //遍历map
        mapOf1.forEach {
            println("${it.key},${it.value}")
        }

        mapOf2.forEach { (key: String, value: Int) ->
            println("$key,$value")
        }
        //可变Map集合
        val mutableMapOf = mutableMapOf("Jack" to 20, "Jason" to 18, "Jack" to 30)
        mutableMapOf += "Jimmy" to 30
        mutableMapOf.put("Jimmy",31)
        mutableMapOf.getOrPut("Rose"){18}
        println(mutableMapOf)

 18.定义类

field关键字:

class Player {

    var name: String = "jack"
        get() = field.capitalize()
        set(value) {
            field = value.trim()
        }

}

fun main() {
    var p = Player()
    println(p.name)
    p.name = " rose "
    println(p.name)
}

 当get、set方法与属性(此处是name)无关时,不需要用到field。如下图,get方法的结果是1-6随机排序的第一个数。

 19.对象初始化

 主构造函数:

class PlayerSecond(
    //_开头表示临时变量
    _name: String,
    _age: Int,
    _isNormal: Boolean
) {
    var name = _name
        get() = field.capitalize()
        set(value) {
            field = value.trim()
        }
    var age = _age
    get() = age.absoluteValue
    set(value) {
        field = age.absoluteValue
    }
    var isNormal = _isNormal

}

fun main(){
    val p = PlayerSecond("Jack", 20, true)
    p.name = "rose"
}

在主构造函数中定义属性:

class PlayerSecond(
    //_开头表示临时变量
    _name: String,
    var age: Int,
    var isNormal: Boolean
) {
    var name = _name
        get() = field.capitalize()
        set(value) {
            field = value.trim()
        }

}

次构造函数:

class PlayerSecond(
    //_开头表示临时变量
    _name: String,
    var age: Int,
    var isNormal: Boolean
) {
    var name = _name
        get() = field.capitalize()
        set(value) {
            field = value.trim()
        }
    //次构造函数
    constructor(name:String):this(name,age = 10,isNormal = false)

    constructor(name:String,age:Int):this(name,age = 10,isNormal = false){
        this.name = name.toUpperCase()
    }
}

fun main(){
    val p = PlayerSecond("Jack", 20, true)
//    p.name = "rose"
    //调用次构造函数
    val p2 = PlayerSecond("Rose")

    val p3 = PlayerSecond("Jacky",20)
    println(p3.name)
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值