笔记:《第一行代码:第3版》 第二章

640 阅读6分钟

笔记:《第一行代码:第3版》 第二章

编程之本:变量和函数

变量

  1. val(value简写) 表示不可变变量。在初始化后不可修改相当于Java中的final变量
  2. var(variable简写) 表示可变变量。初始化后可以修改
//声明以后age不可变了 
val age = 10
age = 20 // [X] Val cannot be reassigned
var name = "张三"
name = "李四"
  1. 变量类型:关键字 变量明:类型 (val a:Int = 10
  2. 如果变量声明时直接赋值可省略类型 (val b = 10), kotlin会自动推导类型为Int

val a:Int = 10

val b = 10

Java 和 Kotlin 数据类型对照表

Java基本数据类型 Kotlin数据类型 说明
int Int 整型
long Long 长整型
short Short 短整型
float Float 单精度浮点型
double Double 双精度浮点型
boolean Boolean 布尔型
char Char 字符型
byte Byte 字节型

函数

fun 函数名(变量名:类型):返回类型{}

//无参数、无返回类型
fun main(){

}
//有参数 、返回类型
fun largerNumber(num1:Int,num2:Int):Int{
      return max(num1,num2)
}

当函数中只有一行代码时,可以使用语法糖进行简写,由于Kotlin可推导变量类型,返回类型可省略


fun largerNumber(num1:Int,num2:Int):Int = max(num1,num2)
//可省略返回类型
fun largerNumber(num1:Int,num2:Int)  = max(num1,num2)

程序的逻辑控制

if条件语句

if语句 和Java 中的 if 几乎没有任何区别,不同之处是Kotlin中的if语句可以有返回值,最后一行代码就是返回值

fun largerNumber(num1:Int,num2:Int):Int {
    var value =0
    if(num1>num2){
        value = num1
    }else{
        value = num2
    }
    return value
}

可以简化为以下


fun largerNumber(num1:Int,num2:Int):Int {
    var value = if(num1>num2){
        value = num1
    }else{
        value = num2
    }
    return value
}

//从上面发现 value是个多余变量,可以改写
fun largerNumber(num1:Int,num2:Int):Int {
    return if(num1>num2){
        num1
    }else{
       num2
    }
}

//可以使用语法糖
fun largerNumber(num1:Int,num2:Int): =  if(num1>num2) num1 else num2

when条件语句

when类似与Java中的Switch,但是又比它强大

/1. when 带参数用法
when(条件){
  匹配值->{执行逻辑,最后一行代码为返回值}
}

fun getScore(name) = when(name){
  "张三"-> 86
  "李四"-> 90
  "王五"-> 100
  else -> 0
}

2. when 不带参数用法
fun getScore(name) = when{
  name.startsWith("张")-> 86
  name=="李四"-> 90
  name=="王五"-> 100
  else -> 0
}

循环语句

forwhile 其中whileJava用法一致 ,Kotlin不支持for-i循环,改为了 for-in循环

//表示区间[0,10]
val range = 0 .. 10 
for(i in 0 .. 10 ){
    println(i)
}
//结果 0 1 2 3 4 5 6 7 8 9 10

//表示区间[0,10)
val range = 0 until 10 
for(i in range ){
    println(i)
}
//结果 0 1 2 3 4 5 6 7 8 9 


//表示区间[10,1]
val range = 10 downTo 1
for(i in range ){
    println(i)
}
//结果 10 9 8 7 6 5 4 3 2 1

//step 关键字 相当于Java for - i i+2
val range = 0 until 10 step 2 
for(i in range ){
    println(i)
}
//结果 0  2  4  6  8

面向编程

  1. 类和对象

Kotlin中的类使用 class表示,对象实例化不需要 new 关键字 直接 对象名()

class Person{
    var name = ""
    var age = 0
    
}
//实例化
val p = Person()
  1. 继承和构造函数

Kotlin默认非抽象类不可以被继承,要想被继承需要使用open关键字 使用 : 继承

open class Person{
    var name = ""
    var age = 0
    
}
class Student :Person(){
    var son=""
    var grade = 0
}

构造函数分为主构造函数 和 次构造函数,其中由于主构造函数没有函数体,Kotlin 提供了 init 结构体,次构造函数需要使用关键字 constructor 。父类后面带的()表示主构造函数,如果既有主构造函数又有次构造函数,所有次构造函数必须实现主构造函数

open class Person(val name:String,val age:Int){
}
class Student(val son:String,val grade :Int, name:String, age:Int) :Person(name,age){
    init{
      //逻辑
    }
}

class Student(val son:String,val grade :Int, name:String, age:Int) :Person(name,age){
    
    constructor(name,String,age:Int):this("",0,name,age){}
    constructor():this("",0){}
    
}

//如果没有主构造函数,只有次构造函数
class Student:Person{
   constructor(name,String,age:Int):sper(name,age){}
}

接口

interface 表示接口,使用:实现接口,如果有多个用,隔开,同时Kotlin允许接口中定义的函数进行默认实现

interface Study{
  fun readBooks()
  fun doHomework(){
      println("xxxxxxx")
  }
}

class Student(val son:String,val grade :Int, name:String, age:Int) :Person(name,age),Study{
    override fun readBooks(){
      
    }

}

修饰符

修饰符 Java Kotlin
pulic 所有类可见 所有类可见(默认)
private 当前类可见 当前类可见
protected 当前类、子类、同一包路径下的类可见 当前类、子类可见
default 同一包路劲下的类可见(默认)
internal 同一模块中的类可见

数据类和单例

类前面加上data表示数据类 object表示单例

data class Student(val name:String,val age:String) 

object Singletion{
  fun say(){}
}

Singletion.say()

Lambda 编程

集合

 /**
  *list
  *listOf 不可变
  *mutableListOf 可变
  **/
val list = listOf("1","2")

val list = mutableListOf("1","2")
list.add("3")
for(value in list){
  println(value)
}

/**
  *set
  *setOf 不可变
  *mutableSetOf 可变
  **/
val set = setOf("1","2")

val set = mutableSetOf("1","2")
set.add("3")
for(value in set){
  println(value)
}

/**
  *map
  *mapOf 不可变
  *mutableMapOf 可变
  **/
val map = mapOf("a" to 1,"b" to 2)

val map = mutableMapOf("a" to 1,"b" to 2)
map["c"]=3
for((key,value) in map){
  println(key + value)
}


函数API

Lambda表达式 {参数名1:参数类型,参数名2:参数类型 : 返回类型-> 函数体}

val list = listOf("Apple","Banana","Orange","Pear","Grape","Watermelon")

val lambda = {fruit:String->fruit.length}

val maxLengthFruit= list.maxBy(lambda)

//可简化 去掉变量lambda
val maxLengthFruit= list.maxBy({fruit:String->fruit.length})
 
//继续简化 使用类型推导去掉返回类型
val maxLengthFruit= list.maxBy({fruit->fruit.length})

//再简化,如果lambda是函数的最后一个参数,可以放到括号外面,省略括号
val maxLengthFruit= list.maxBy{fruit->fruit.length}

//终极简化,如果lambda是函数的唯一参数,可以不声明参数名,用it代替
val maxLengthFruit= list.maxBy{ it.length }

集合常用函数API

  1. map函数 可将集合中的每个元素修改成别的值,最终生成新集合
  2. filter函数 过滤集合中的元素数据
  3. any函数 判断集合中是否至少有一个元素满足条件
  4. all函数 判断集合中所有元素是否满足条件

Java函数式API使用

如果Java的一个接口满足只有一个待实现的方法,J就可以使用函数式API,例如:View的点击事件OnClickListener它只有一个方法onClick

btn.setOnClickListener{
    
}

空指针检查

var a:String?=""声明的变量类型后面带有?表示改变量可以为null ?.操作符相当于if(a!=null){...} ?:操作符相当于if(a!=null){return a}else{return b}


fun doStudy(study:Study?){
    study?.readBooks()
    study?.doHomework()
}

val a:String?=null
val c = if(a!=null){ a } else {b}
val c = a?:b

let函数

let函数,提供了函数式API的编程接口,并将原始调用对象作为参数传递到了Lambda表达式中


fun doStudy(study:Study?){
    study?.readBooks()
    study?.doHomework()
}

//使用let
fun doStudy(study:Study?){
    study?.let{
        it.readBooks()
        it.doHomework()
    }
}

Kotlin中的小魔术

字符串内嵌表达式

val name= "张三"
val a = "My name is $name"

函数的默认参数

fun printParams(num:Int,str:String="hello"){
    println("num is $num str is $str")
}

printParams(100)

fun printParams(num:Int=100,str:String){
    println("num is $num str is $str")
}
//使用键值对 key就是参数名
printParams(str="hello")

END

本文使用 mdnice 排版