Kotlin实战(四)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zping0808/article/details/85174602

一、区间

1.1、区间定义

  /*------------定义1到100区间------------*/
    val a = 1..100//[1,100]
    val b = 1 until 100 //[1,100)
    val c = 1.rangeTo(100)//[1,100]
    val d = IntRange(1, 100)//[1,100]

    /*------------长整型区间------------*/
    val a1 = 1L..100L
    val b1 = 1L until 100L
    val c1 = 1L.rangeTo(100L)
    val d1 = LongRange(1L, 100L)

    /*------------字符区间------------*/
    val a2 = 'a'..'b'
    val b2 = 'a' until 'b'
    val c2 = 'a'.rangeTo('b')
    val d2 = CharRange('a', 'b')

    val aa='你'..'我'

1.2、区间获取值

val a=1.rangeTo(10)
//区间的第一个值
println(a.first)//1
//区间的最后一个值
println(a.last)//10

1.3、区间遍历

    val a = 20..30
    for (i in a) {
        println(i)
    }
    /*-----------------------for循环------------------*/
    //不带角标
    for (i in a) {
        println(i)

    }
    //带角标
    for ((i, withIndex) in a.withIndex()) {
        println("$i-----$withIndex")

    }
    /*-----------------------forEach循环------------------*/
    //不带角标
    a.forEach {
        println(it)
    }
    //带角标
    a.forEachIndexed { index, i ->
        println("$index-----$i")
    }

1.4、反向区间和区间的反转

   /*----------------------- 反向区间 -----------------------*/
    //定义10到1的区间
    val s=10 downTo 1
    s.forEach {
        println(it)
    }

    /*----------------------- 区间反转 -----------------------*/
    val a=1..10
    //区间反转
    val reversed = a.reversed()
    reversed.forEach {
        println(it)
    }

1.5、区间设置步长

//步长必须>=0. 设置区间步长为4 打印结果为  1   5   9
val a=1..10 step 4
for (i in a) {
    println(i)//1 5 9
}

二、数组

2.1、数组的定义

    /*----------定义数组并赋值------------*/
    val arrayOf = arrayOf("1", "N", "0", "Y")
    var arrayOf1 = arrayOf(1, 2, 3)
    var arrayOf2 = arrayOf("1", 2, 'a')

    /*-------- 8种基本数组类型数组 -----------*/

    //定义Int数组
    val s0 = IntArray(10)
    //定义Int数组并赋值
    val s1 = IntArray(10) {
        1//把数组里面每一个元素都初始化为1
    }
//    IntArray
//    BooleanArray
//    LongArray
//    DoubleArray
//    FloatArray
//    ShortArray
//    ByteArray
//    CharArray

2.2、数组打印

val a= arrayOf("1","A","B")
//打印数组,默认以","分隔
println(a.joinToString())//1, A, B
//打印数组,以"、"分隔 开始增加"【" 结束增加 "】"
println(a.joinToString(separator = "、",prefix = "[",postfix = "]"))//[1、A、B]
//数组转字符串
println(a.joinToString(""))//1AB

2.3、数组的遍历

    val a = arrayOf("你", "我", "他")
    /*----------for循环----------*/
    //不带角标
    for (s in a) {
        println(s)
    }
    //带角标
    for ((index, s) in a.withIndex()) {
        println("$index----$s")

    }

    /*----------forEach循环----------*/
    //不带角标
    a.forEach {
        println(it)
    }
    //带角标
    a.forEachIndexed { index, s ->
        println("$index----$s")
    }

2.4、数组元素的修改

    val s = arrayOf(100, 102, 104)
    //把第0位改为121
    s[0] = 121
    //把第1位改为110
    s.set(1, 110)

   s.forEach{
       println(it)
   }

2.5、数组元素角标的查找

    val a = arrayOf("张三", "李四", "王五", "李四", "赵六")

    /*------------普通方法查找-----------*/
    //查找第一个 "李四" 的角标
    println(a.indexOf("李四"))//1 返回第一个对应的元素角标  如果没有找到返回-1
    //查找最后一个 "李四" 的角标
    println(a.lastIndexOf("李四"))//3

    /*------------高阶函数实现-----------*/
    //查找第一个 姓 "李" 的角标
    val index = a.indexOfFirst {
        it.startsWith("李")
    }
    println(index)//1

    //查找最后一个 "李四" 的角标
    val index2 = a.indexOfLast {
        it=="李四"
    }
    println(index2)//3

2.6、数组切片(slice、sliceArray)

//数组切片
val b= intArrayOf(5,2,0,1,3,1)
//截取指定范围数据集合(返回是集合)
val slice = b.slice(2..5)
println(slice)//[0, 1, 3, 1]

//截取指定范围数据数组(返回是数组)
val sliceArray = b.sliceArray(2..5)
println(sliceArray.joinToString())//0, 1, 3, 1

2.7、二维数组及多维数组

//二维数组定义 
val array = Array(2) { IntArray(2) }
    //给数据赋值
    array[0][0]=1
    array[0][1]=2
    //遍历数组
    for ((i,ints) in array.withIndex()) {
        for ((j,int) in ints.withIndex()) {
            println("i=$i,j=$j,int=$int")
        }
    }
//    i=0,j=0,int=1
//    i=0,j=1,int=2
//    i=1,j=0,int=0
//    i=1,j=1,int=0

//三维数组定义
val arrB = Array(3){Array(3){IntArray(3)}}
//三维数组赋值
arrB[0][0][0]=1
arrB[0][0][1]=2
//遍历三维数组
for (one in arrB) {
    for (two in one) {
        for (three in two) {
            println(three)
        }
    }
}

三、函数

3.1、函数定义

//无参无返回值
fun sayHello() {//返回值
    println("hello")
}

//有参无返回值
fun sayHello(name: String) {
    println("hello " + name)
}

//有参有返回值
fun getLength(name: String): Int {
    return name.length
}

//无参有返回值
fun getHello(): String {
    return "hello"
}

3.2、顶层函数

Kotlin中的顶层函数反编译成的Java中的容器类名一般是顶层文件名+“Kt”后缀作为类名,但是也是可以自定义的。也就是说顶层文件名和生成容器类名没有必然的联系。通过Kotlin中的@file: JvmName(“自定义生成类名”)注解就可以自动生成对应Java调用类名,注意需要放在文件顶部,在package声明的前面

//生成Java调用类名,放在文件顶部,在package声明的前面
@file: JvmName("Util")
package com.zp.kotlin
//函数式编程  函数式一等公民 函数可以独立于对象单独存在
//顶层函数
fun helloWord() {

}

3.3、嵌套函数

//顶层函数
fun main(args: Array<String>) {
    //嵌套函数
    fun hello() {
        println("hello")
    }
    hello()
}

3.4、函数表达式

println(add(1, 1))//2
println(add2(1, 1))//2
println(add3(1, 1))//2

fun add(m: Int, n: Int): Int {
    return m + n
}

//函数体只有一行代码  可以省略{} 省略return 用=连接
fun add2(m: Int, n: Int): Int = m + n

//函数体只有一行代码  可以省略{} 省略return 用=连接 返回值类型也不用写
fun add3(m: Int, n: Int) = m + n

3.5、函数表达式补充

/*------------------ 函数引用:: ------------------*/
val a = ::add5
println(a(1, 1))//2
println(a?.invoke(1, 1))//2 可以处理函数变量为空的情况下调用

/*------------------- 函数变量 -------------------*/
//    val b = { m: Int, n: Int -> m + n }
val b: (Int, Int) -> Int = { m, n -> m + n }////匿名函数
println(b(1, 1))//2


fun add5(m: Int, n: Int): Int {
    return m + n
}

3.6、默认参数和具名参数

sendRequest("http://www.baidu.com")//发送请求路径http://www.baidu.com,请求方式GET
sendRequest("http://www.baidu.com", "POST")//发送请求路径http://www.baidu.com,请求方式POST
//具名参数 参数位置可以变化
sendRequest(method = "FILE", path = "http://www.baidu.com")//发送请求路径http://www.baidu.com,请求方式FILE

fun sendRequest(path: String, method: String = "GET") {//="GET" :默认参数
    println("发送请求路径$path,请求方式$method")
}

3.7、可变参数(vararg)

val adds = adds(1, 2, 3)
println(adds)

fun adds(vararg a: Int): Int {//vararg 可变参数,无论你传递多少个我都能求他们的和
    //kotlin 不能直接对函数参数进行重新赋值(a=IntArray(10))
    //a是一个数组类型
    var s = 0
    a.forEach {
        s += it
    }
    return s
}

3.8、可变参数展开操作符(*)

val arrayOf = arrayOf("a", "bb", "ccc")
//为了将数组展开并传入可变参数,Kotlin使用星号(*)操作符将数组进行展开
test(*arrayOf)

fun test(vararg  a:String){
    println(a.toList())//[a, bb, ccc]
}

四、异常

4.1、处理异常

    val a = 10
    val b = 0
    var c: Int = 0

    //异常处理
    try {
        c = a / b
    } catch (e: Exception) {
        println("捕获到异常")
    } finally {
        println("最终要执行的代码")
    }

    println(c)

    /**
     * koltin编译时异常
     * kotlin不检查编译时异常,kotlin认为大部分的编译时异常都是没有必要的
     */
    val file = File("/1.txt")
    val f = BufferedReader(FileReader(file))

4.2、处理异常作为函数表达式返回

//try catch  作为函数表达式
val a: Int? = try {
    "abc".toInt()
} catch (e: Exception) {
    null
}
println(a)//null

五、递归

5.1、递归实现

val a = 4
println("$a 的阶乘是${fact(a)}")//4 的阶乘是24
println("第$a 个斐波那契数列是${fibonacci(a)}")//第4 个斐波那契数列是3

/**
 * 求n的阶乘
 * 分析:n的阶乘 = n *(n-1)的阶乘 ,1的阶乘是1
 */
fun fact(n: Int): Int {
    if (n == 1) {
        return 1
    } else {
        return n * fact(n - 1)
    }
}

/**
 * 求n个斐波那契数列(1 1 2 3 5 8 13 21 34 55……)
 * 分析:第n个斐波那契数列=第n-1个斐波那契数列+第n-2个斐波那契数列,第1个斐波那契数列是1,第2个斐波那契数列是1
 */

fun fibonacci(n: Int): Int {
    if (n == 1 || n == 2) {
        return 1
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2)
    }
}

5.2、递归和迭代的对比

 /**
 * 常见的需求:通过迭代和递归都可以解决 复杂的问题用递归更容易实现
 * StackOverflowError 递归如果递归的层级比较深容易栈内存溢出
 * 递归:优点:逻辑比较简单  容易实现  缺点:容易栈内存溢出(内存开销比较大)
 * 迭代:优点:内存开销小 缺点:抽象出数学模型
 */
val n = 5
println("1到$n 的和为${sum1(n)}")//1到5 的和为15
println("1到$n 的和为${sum2(n)}")//1到5 的和为15

/**
 * 递归方法求和
 * 求1+2+……+n的和
 * 分析:1到n的和 = n+ 1到(n-1)的和  1到1的和=1
 */
fun sum1(n: Int): Int {
    if (n == 1) {
        return 1
    } else {
        return n + sum1(n - 1)
    }

}

/**
 * 迭代方法求和
 * 求1+2+……+n的和
 */
fun sum2(n: Int): Int {
    //kotlin里面参数是固定  不能修改 所以var newN = n
    var newN = n
    var s = 0
    while (newN > 0) {
        s += newN
        newN--
    }
    return s
}

5.3、尾递归优化

/**
 * 尾递归:调用了自身之后没有其他操作
 * 只有是尾递归才可以做尾递归优化
 */
val n = 5
println("1到$n 的和为${sum3(n)}")//1到5 的和为15
println("1到$n 的和为${sum4(n)}")//1到5 的和为15

/**
 * 原始递归求和
 * 求1+2+……+n的和
 * 分析:1到n的和 = n+ 1到(n-1)的和  1到1的和=1
 */
fun sum3(n: Int, result: Int = 0): Int {
    if (n == 1) {
        return 1
    } else {
        return sum3(n - 1) + n//调用自身之后做了其他操作,非尾递归
    }
}

/**
 * 尾递归优化求和
 * 求1+2+……+n的和
 * 尾递归优化步骤:
 * 第一步:需要将递归转换为尾递归
 * 第二步:加上tailrec
 * 尾递归优化的原理:将递归转换为迭代(while循环)
 */
tailrec fun sum4(n: Int, result: Int = 0): Int {
    if (n == 1) {
        return result + 1
    } else {
        return sum4(n - 1, result + n)//调用了自身之后没有其他操作,是尾递归
    }
}

猜你喜欢

转载自blog.csdn.net/zping0808/article/details/85174602