Kotlin学习日志(三)控制语句

一、条件分支

1.1 简单分支

最简单的分支莫过于if…else了吧,Java中相信都用过,那么在Kotlin中又是怎么用的呢?其实也比较类似,来看看吧!
布局文件中:

<TextView
        android:layout_marginTop="20dp"
        android:textColor="#000"
        android:padding="20dp"
        android:id="@+id/tv_puzzle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_if_else"
        android:text="IF ELSE"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

代码中

var is_odd:Boolean = true
        tv_puzzle.text = "随心所欲,为所欲为,二选一"
        btn_if_else.setOnClickListener {
            if(is_odd == true){
                tv_puzzle.text = "随心所欲"
            }else{
                tv_puzzle.text = "为所欲为"
            }
            is_odd = !is_odd
        }

运行效果图
在这里插入图片描述

点一下按钮:
在这里插入图片描述
再点一下:
在这里插入图片描述
点击次数为奇数时显示 随心所欲,为偶数时显示 为所欲为,但是上面的代码和Java不是一毛一样吗?特养特僧破,我们注意到无论是奇数还是偶数点击,都是显示在这个TextView上面,Kotlin在这里做的优化便是允许分支语句返回字符串,从而在条件语句外层直接对tv_puzzle赋值,优化之后如下所示:

btn_if_else.setOnClickListener {
            tv_puzzle.text = if(is_odd == true){
                "随心所欲"
            }else{
                "为所欲为"
            }
            is_odd = !is_odd
        }

判断还是原来的判断但是,更加的精简了,再优化一下去掉这个大括号,如下所示

btn_if_else.setOnClickListener {
            tv_puzzle.text = if(is_odd == true) "随心所欲" else "为所欲为"
            is_odd = !is_odd
        }

一个if…else…语句一行代码就可以了,精简至此,夫复何求!
说完了简单分支,接下来说一下多路分支

1.2 多路分支

多说多路分支,你首先想到的是不是switch/case呢?但是switch/case存在自身的局限性,Kotlin推出新的关键字,when/else,使用这个来处理多路分支的条件判断:

var count:Int = 0
        btn_when_else.setOnClickListener {
            when(count){
                0 -> tv_result.text = "你说你有点难追"
                1 -> tv_result.text = "我就打断你的腿"
                //if语句可以没有else,但是when语句必须带上else
                else -> tv_result.text = "《告白气球》"
            }
            count = (count + 1 ) % 3
        }

运行后的效果就是点击按钮之后不同的文字出现,出现的条件由count = (count + 1 ) % 3的结果控制
对比when/else和switch/case,有以下区别
(1)关键自switch被when取代
(2)判断语句“case 常量值:” 被新语句 “常量值 ->”取代
(3)每个分支后面的break语句取消了,因为Kotlin默认一个分支处理完就直接跳出多路语句,所以不需要break。
(4)关键自default被else取代。
就像之前我们优化if/else一样,Kotlin中的when/else也允许有返回值,所以上面的代码还可以再优化,优化后代码如下:

var count:Int = 0
        btn_when_else.setOnClickListener {
            tv_result.text = when(count){
                0 -> "你说你有点难追"
                1 -> "我就打断你的腿"
                else ->  "《告白气球》"
            }
            count = (count + 1 ) % 3
        }

还有一点就是以往Java使用switch/case时有个限制,就是case后面只能跟常量,不能跟变量,否则编译不通过,现在Kotlin去掉了这个限制,进行了分支处理是允许引入变量判断,当然引入具体的运算表达式也是可以的,代码演示如下:

var odd:Int = 0
        var event:Int = 1
        var count:Int = 1
        btn_when_else.setOnClickListener {
            tv_result.text = when(count){
                odd -> "你说你有点难追"
                event -> "我就打断你的腿"
                else ->  "《告白气球》"
            }
            count = (count + 1 ) % 3
        }

在Java中的switch/case机制中,每个case仅仅对应一个常量值,如果5个常量值都要进入某个分支,就只能并列写5个case语句,然后才跟上具体的分支处理语句,现在when/else机制中便无须如此麻烦了,这5个常量值并排在一起用逗号隔开即可,如果几个常量刚好是连续数字,可以使用“in 开始值…结束值”指定区间范围,举一反三,若要求不在某个区间范围,则使用语句“!in 开始…结束值”。扩展功能后的多路分支代码如下所示:

var count:Int = 1
        btn_when_else.setOnClickListener {
            tv_result.text = when(count){
                1,3,5,7,9 -> "你说你有点难追"
                in 13..19 -> "我就打断你的腿"
                !in 6..10 -> "周杰伦"
                else ->  "《告白气球》"
            }
            count = (count + 1 ) % 20
        }

虽然已经知道这种方式了,但在要熟练运用还有一些实践才行,而不是写几个示例就可以掌握的,路漫漫其修远兮,吾将上下而求索!

1.3 类型判断

在Java代码若想知道某个变量是否为字符串类型,则使用一下代码格式进行判断

if(str instanceof String){
	...
}

而在Kotlin中,关键字instanceof被is所取代,下面是示例代码:

if(str is String){
	...
}

同事,多路分支的when/else语句也支持类型判断,只不过在分支判断时采取"is 变量类型 ->"这种形式,下面是代码示例,在变量countType为Long、Double、Float三种类型时做多路判断处理:
布局文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_marginTop="20dp"
        android:textColor="#000"
        android:padding="20dp"
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_when_instance"
        android:text="WHEN INSTANCE"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

MainActivity.kt

package com.llw.kotlinstart

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var count:Int = 1
        var countType:Number
        btn_when_instance.setOnClickListener {
            count = (count + 1) % 3
            countType = when(count){
                0 -> count.toLong()
                1 -> count.toDouble()
                else -> count.toFloat()
            }
            tv_result.text = when(countType){
                is Long -> "天若有情天亦老"
                is Double -> "人间正道是沧桑"
                else -> "无问西东"
            }
        }


    }
}

判断类型为Long 时,运行效果图 如下
在这里插入图片描述

判断类型为Double 时,运行效果图 如下
在这里插入图片描述
为其他类型 时,运行效果图 如下
在这里插入图片描述

二、循环处理

2.1 遍历循环

Java遍历某个队列,可以通过“for(item:list)”形式的语句进行循环操作。同样,Kotlin也能使用类似形式的循环,区别在于吧冒号“:”换成了关键字“in”,示例代码如下:
布局文件的代码我就不贴了,都差不多
直接看代码吧

val txArray:Array<String> = arrayOf("十年生死两茫茫","不思量","自难忘","千里孤坟",
            "无处话凄凉","纵使相逢应不识","尘满面","鬓如霜","夜来幽梦忽还乡","小轩窗","正梳妆",
            "相顾无言","惟有泪千行","料得年年肠断处","明月夜","短松冈")
        btn_test.setOnClickListener {
            var desc:String = ""
            for (item in txArray){
                desc = "$desc$item, \n"
            }
            tv_result.text = desc
        }

运行效果图如下:
在这里插入图片描述
但是一首词不可能结尾都是逗号,所以要改一下判断的代码,同时也改一下文章的格式,改为七言绝句,奇数为逗号,偶数为句号,在Kotlin中使用“for(i in 数组变量.indices)”语句,其中indices表示该数组变量的下标数组,每次循环从下表数组依次取出当前元素的下标,代码如下:

val txArray:Array<String> = arrayOf("日照香炉生紫烟","遥看瀑布挂前川","飞流直下三千尺","疑是银河落九天")
        btn_test.setOnClickListener {
            var desc:String = ""
            //indices表示该数组变量的下标数组
            for (i in txArray.indices){
                if (i % 2 == 0){
                    desc = "$desc${txArray[i]},\n"
                }else{
                    desc = "$desc${txArray[i]}。\n"
                }
            }
            tv_result.text = desc
        }

运行效果图:
在这里插入图片描述

2.2 条件循环

使用while进行循环判断,示例代码如下:

val txArray:Array<String> = arrayOf("日照香炉生紫烟","遥看瀑布挂前川","飞流直下三千尺","疑是银河落九天")
        btn_test.setOnClickListener {
            var poem:String = ""
            var i:Int = 0
            while (i < txArray.size){
                if(i % 2 == 0){
                    poem = "$poem${txArray[i]}, \n"
                }else{
                    poem = "$poem${txArray[i]}。 \n"
                }
                i++
            }
            poem = "${poem}该诗歌一共有${i}句。"
            tv_result.text = poem
        }

再来看看do/while

val txArray:Array<String> = arrayOf("日照香炉生紫烟","遥看瀑布挂前川","飞流直下三千尺","疑是银河落九天")
        btn_test.setOnClickListener {
            var poem:String = ""
            var i:Int = 0
            do {
                if(i % 2 == 0){
                    poem = "$poem${txArray[i]}, \n"
                }else{
                    poem = "$poem${txArray[i]}。 \n"
                }
                i++
            }while (i < txArray.size)
            poem = "${poem}该诗歌一共有${i}句。"
            tv_result.text = poem
        }

2.3 跳出多重循环

之前的诗句都是中规中矩的,没有什么问题,但是实际开发中则不然,所以合理性判断时很重要的,Kotlin中的判断代码如下

val txArray:Array<String?> = arrayOf("日照香炉生紫烟",null,"遥看瀑布挂前川","","飞流直下三千尺","     ","疑是银河落九天","望庐山瀑布")
        btn_test.setOnClickListener {
            var poem:String =""
            var pos:Int = -1
            var count:Int = 0
            while (pos <= txArray.size){
                pos++
                //若发现该行时空串或者空格串,则忽略该行
                if(txArray[pos].isNullOrBlank())
                    continue
                if(count % 2 == 0){
                    poem = "$poem${txArray[pos]},\n"
                }else{
                    poem = "$poem${txArray[pos]}。\n"
                }
                count++
                //若合法行数达到4行,则结束循环
                if(count == 4)
                    break
            }
            tv_result.text = poem
        }

从上面的代码来看,合法性的判断用到的是continue和break,和Java一样,那么Kotlin真的就没有做什么改变吗?其实不然,Kotlin中,只要遇到有异常情况即可跳出循环,不管你是单层循序还是多层循环,说的跟真的一样,我们来实现一下吧

val txArray:Array<String?> = arrayOf("日照香炉生紫烟",null,"遥看瀑布挂前川","","飞流直下三千尺","     ","疑是银河落九天","望庐山瀑布")

        btn_test.setOnClickListener {
            var i:Int = 0
            var is_found = false
            //给外层循环加一个名为outside的标记
            outside@ while (i < txArray.size){
                var j:Int = 0
                var item = txArray[i]

                if (item != null) {
                    while ( j < item.length){
                        if(item[j] == '飞'){
                            is_found = true
                            //发现 这个飞 字直接跳出outside循环
                            break@outside
                        }
                        j++

                    }
                }
                i++
            }
            tv_result.text = if (is_found) "有" else "无"
        }

上面的代码运行效果如下
在这里插入图片描述
上面的循环与判断时多层的,直接跳出显示结果,这就是 用了 @ 的好处,这也是Kotlin中的新的改变。未完待续。。。

发布了27 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_38436214/article/details/104424241