Kotlin基础

文章目录

    • 一. Kotlin 基础知识
      • 1. HelloWorld:
      • 2、常见数据类型
      • 3、类型推断
      • 4、取值范围
      • 5、函数
      • 6、字符模版
      • 7、字符串比较
      • 8、方法参数与null
      • 9、when 条件语句
      • 9、循环 和 区间
      • 10、list 与 map
      • 11、函数式表达式
      • 12、默认参数和具名参数
      • 13、Stirng 与 Int 互转
      • 14、异常处理
      • 15、尾递归优化
    • 二、面向对象
      • 1、继承
      • 2、接口
      • 3、代理和委托 by
      • 4、单例 object
      • 5、枚举 和 印章类
    • 三、高阶函数(参数/返回值为函数 )(forEach,map,flatmap,fold,reduce,filter,takeWhite,let/run,also/apply,with,use)
      • 1、let函数适用的场景
      • 2、with函数的适用的场景
      • 3、run函数的适用场景
      • 4、apply 适用场景
    • 四、DSL(特定领域语言)
    • 五、闭包

一. Kotlin 基础知识

1. HelloWorld:

fun main(args: Array<String>){
     
    System.out.println("hello world")
}

2、常见数据类型

Kotlin基础_第1张图片

3、类型推断

4、取值范围

var aByte:Byte = Byte.MAX_VALUE
var bByte:Byte = Byte.MIN_VALUE

5、函数

fun checkAge(age: Int): Boolean{
     
    if(age > 18) return true else return false
}

6、字符模版

fun diaryGeneraer(placeName: String){
     
    var temple = """今天天气晴朗,万里无云,我们去${
       placeName}游玩,"""
    println(temple)
}

7、字符串比较

与Java中不一样,kotlin中 “==” 和 equals() 一样,equals( , true)是忽略大小写

8、方法参数与null

fun test(){
     
    heat(null)     //编译过
    heat1(null)    //编译不过
}

//参数str可以传null
fun heat(str: String?): String{
     
     return str + "热"
}

//参数str 不可以传null
fun heat1(str: String): String{
     
    return str + "热"
}

9、when 条件语句

fun gradeStudent(score: Int){
     
    when(score){
     
        10 -> println("考了满分")
        8 -> println("还可以")
        6 -> println("刚好及格")
        3 -> println("不行哦")
        else -> println("other")
    }
}

when 条件语句进阶

fun diaryGenerator(placeName: String){
     
    var diary = """今天天气晴朗,我们去了${
       placeName}玩,
        |刚进大门首先印入眼帘的是${
       placeName}
        |${
       strNum(placeName.length)}个镏金大字""".trimMargin()

    print(diary)
}


fun strNum(score: Int): String{
     
   var result = when(score){
     
        1 -> "一"
        2 -> "二"
        3 -> "三"
        4 -> "四"
        else -> "地名太长了"
    }
    return result
}

9、循环 和 区间

fun main(): Unit{
     
    var nums = 1 .. 100   //闭区间[1, 100]
    var result = 0;
    for(num in nums){
          //循环:in可以把数组中的数字取出来
        result = result + num
    }

    print("结果是" + result)
    print("结果是${
       result}")
}

开区间:
var nums = 1 until 100   //闭区间[1, 100)

step:
var nums = 1 .. 100
for(num in nums step 2){
     
    print("${
       num} ,")
}

反转:
var nums = 1 .. 100
var nums1 = nums.reversed();
for(num in nums1 step 2){
     
    print("${
       num} ,")
}

10、list 与 map

  1. list不带index
var lists = listOf<String>("大米", "鸡蛋", "小米", "薏米")
for(str in lists){
     
    print(str)
}
  1. list带index
var lists = listOf<String>("大米", "鸡蛋", "小米", "薏米")
for((i, str) in lists.withIndex()){
     
    print("" + i + " " + str)
    print("$i  $str")
}
  1. Map
var map = HashMap<String, String>()
map["good"] = "好"
map["yes"] = "是"
map["no"] = "不"

for(str in map){
     
    println(str)
}

println(map.get("good"))
println(map["good"])

11、函数式表达式

//1、
fun add(x: Int, y: Int): Int{
     
    return x + y
}

//2、当函数体只有一句代码时:,
fun add(x: Int, y:Int):Int = x + y

//3、还可以写成这样
var sum = {
     x:Int, y:Int -> x+y}
var i = sum(3, 5)    //调用

//4、
var sum1:(Int, Int) -> Int = {
     x,y -> x + y}

12、默认参数和具名参数

fun main(): Unit{
     
    sum()
    sum(1, 3)
    sum(x = 3)
    sum(y = 9)   //具名参数
}

//默认参数
fun sum(x:Int = 2, y:Int = 5): Int{
     
    return x + y
}

13、Stirng 与 Int 互转

fun main(): Unit{
     
    var str = "123"
    var int = 123;
    var strInt = "123abc"

    int  = str.toInt();
    str = int.toString();
    int = strInt.toInt();   //编译器会报错java.lang.NumberFormatException: For input string: "123abc"
}

14、异常处理

while (true) {
     
    println("请输入数字")
    var str = readLine()
    try {
     
        var int = str!!.toInt()
    }catch (e: Exception){
     
        println("大哥,要输入数字哦")
    }
}

15、尾递归优化

二、面向对象

1、继承

open class Fathor{
                //被继承需要open
    var chactor: String = "性格内向"
    open fun action(){
           //被复写需要open
        println("喜欢思考")
    }
}

class Son: Fathor(){
       
    override fun action() {
           //复写需要override
        println("儿子很乖")
    }
}

2、接口

interface Iman {
     
    fun say()
}

abstract class Human(var name:String){
     
    abstract fun eat()
}

class Man(name: String) : Human(name), Iman {
     

    override fun eat() {
     
        println("大口吃")
    }

    override fun say() {
     
    }
}

3、代理和委托 by

interface IWash {
     
    abstract fun wash();
}

class BigHeadChild : IWash {
     
    override fun wash() {
     
    }
}

class SmallHeadFather : IWash by BigHeadChild(){
     
   override fun wash() {
     
        println("我是大头爸爸,儿子帮我洗碗")
        BigHeadChild().wash()
   }
}
 

4、单例 object

object BigHeadChild : IWash {
     
    override fun wash() {
     
    }
}

调用的时候()去掉
class SmallHeadFather : IWash by BigHeadChild{
     

    override fun wash() {
     
        println("我是大头爸爸,儿子帮我洗碗")
        BigHeadChild.wash()
    }
}

5、枚举 和 印章类

枚举:注重数据

fun main(): Unit{
     
    println(Week.星期一)
    println(Week.星期一.ordinal)
}

enum class Week{
     
    星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期日,
}

印章类:注重类型

fun main(): Unit{
     
    var s1:Son = Son.小小驴()
    var s2:Son = Son.骡子()
}

sealed class Son{
     
    fun sayHello(){
     
        println("大家好")
    }
    class 小小驴() : Son()
    class 骡子(): Son()
}

三、高阶函数(参数/返回值为函数 )(forEach,map,flatmap,fold,reduce,filter,takeWhite,let/run,also/apply,with,use)

//maxBy
printGirl(grilList.maxBy {
      it.height })    //Java 中需要遍历一遍

//minby
printGirl(grilList.minBy {
      it.height })

//filter
println(grilList.filter {
     
    (it.height > 123) and (it.height < 1234)
})

//map
var result = grilList.map {
      "${
       it.name} : ${
       it.height}" }
println(result)

//any  是否有
println(grilList.any{
      it.height == 1253})

//count
println(grilList.count{
      it.height <= 1253})

//find 查找第一个符合条件的
println(grilList.find{
      it.height == 1253})

//groupBy   根据不同的条件分组
println(grilList.groupBy{
      it.address})
println(grilList.groupBy{
      it.address}.get("北京"))
println(grilList.groupBy{
      it.address}.get("北京")?.forEach {
      printGirl(it) })

//let
grilList.get(0)?.let {
      printGirl(it) }

1、let函数适用的场景

参考:https://blog.csdn.net/u013064109/article/details/78786646
场景一: 最常用的场景就是使用let函数处理需要针对一个可null的对象统一做判空处理。
场景二: 然后就是需要去明确一个变量所处特定的作用域范围内可以使用

不使用let,不够优雅

mVideoPlayer?.setVideoView(activity.course_video_view)
mVideoPlayer?.setControllerView(activity.course_video_controller_view)
mVideoPlayer?.setCurtainView(activity.course_video_curtain_view
)

使用let
mVideoPlayer?.let {
     
           it.setVideoView(activity.course_video_view)
           it.setControllerView(activity.course_video_controller_view)
           it.setCurtainView(activity.course_video_curtain_view)
}

2、with函数的适用的场景

适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上:

没有使用with前:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
     

   ArticleSnippet item = getItem(position);
              holder.tvNewsTitle.setText(StringUtils.trimToEmpty(item.titleEn));
           holder.tvNewsSummary.setText(StringUtils.trimToEmpty(item.summary));
                String gradeInfo = "难度:" + item.gradeInfo;
                String wordCount = "单词数:" + item.length;
                String reviewNum = "读后感:" + item.numReviews;
                String extraInfo = gradeInfo + " | " + wordCount + " | " + reviewNum;
                holder.tvExtraInfo.setText(extraInfo);
                ...
}

使用with后:   $代替item
override fun onBindViewHolder(holder: ViewHolder, position: Int){
     
   val item = getItem(position)?: return
   with(item){
     
      holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)
           holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)
           holder.tvExtraInf.text = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"
       ...   
   }
}

3、run函数的适用场景

适用于let,with函数任何场景。因为run函数是let,with两个函数结合体,准确来说它弥补了let函数在函数体内必须使用it参数替代对象,在run函数中可以像with函数一样可以省略,直接访问实例的公有属性和方法,另一方面它弥补了with函数传入对象判空问题,在run函数中可以像let函数一样做判空处理。

run函数使用前:

override fun onBindViewHolder(holder: ViewHolder, position: Int){
     
   val item = getItem(position)?: return
   with(item){
     
           holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)
           holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)
           holder.tvExtraInf = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"
       ...   
  
   }
}

使用run后:

override fun onBindViewHolder(holder: ViewHolder, position: Int){
     
  getItem(position)?.run{
     
      holder.tvNewsTitle.text = StringUtils.trimToEmpty(titleEn)
           holder.tvNewsSummary.text = StringUtils.trimToEmpty(summary)
           holder.tvExtraInf = "难度:$gradeInfo | 单词数:$length | 读后感: $numReviews"
       ...   
   }
}

4、apply 适用场景

整体作用功能和run函数很像,唯一不同点就是它返回的值是对象本身,而run函数是一个闭包形式返回,返回的是最后一行的值。正是基于这一点差异它的适用场景稍微与run函数有点不一样。
apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值。或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到,这种情景非常常见。特别是在我们开发中会有一些数据model向View model转化实例化的过程中需要用到。

没有使用apply函数的代码是这样的:

mSheetDialogView = View.inflate(activity, R.layout.layout_sheet_inner, null)
mSheetDialogView.course_comment_tv_label.paint.isFakeBoldText = true
mSheetDialogView.course_comment_tv_confirm.paint.isFakeBoldText = true
mSheetDialogView.course_comment_seek_bar.max = 10
mSheetDialogView.course_comment_seek_bar.progress = 0

使用apply函数后的代码是这样的:

mSheetDialogView = View.inflate(activity, R.layout.layout_sheet_inner, null).apply{
     
   course_comment_tv_label.paint.isFakeBoldText = true
   course_comment_tv_score.paint.isFakeBoldText = true
   course_comment_seek_bar.max = 10
   course_comment_seek_bar.progress = 0
}

多层级判断:

if (mSectionMetaData == null || mSectionMetaData.questionnaire == null || mSectionMetaData.section == null) {
     
       return;}
       if (mSectionMetaData.questionnaire.userProject != null) {
     
             renderAnalysis();
             return;}
             if (mSectionMetaData.section != null) {
     
                   fetchQuestionData();
                   return;}

apply优化后:

mSectionMetaData?.apply{
     
     //mSectionMetaData不为空的时候操作mSectionMetaData
}?.questionnaire?.apply{
     
    //questionnaire不为空的时候操作questionnaire
}?.section?.apply{
     
     //section不为空的时候操作section
}?.sectionArticle?.apply{
     
    //sectionArticle不为空的时候操作sectionArticle
}

四、DSL(特定领域语言)

只有一个参数,且用infix修饰的函数

//书
class Book{
     
    //infix 自定义运算符的中缀表达式。本没有on,自定义一个,不需要类名.方法即可调用
    //传入任意类型,返回一个Boolean类型的参数
    infix fun on(any: Any): Boolean{
     
        return true
    }
}
//桌子
class Desk

fun main(args: Array<String>) {
     
    if(Book() on Desk()){
     
        println("书在桌上")
    }
}

五、闭包

kotlin学习笔记之闭包

你可能感兴趣的:(kotlin,android)