Kotlin学习日志(二)数据类型(下)

简介: Kotlin学习日志(二)数据类型(下)

MainActivity.kt里面中新增如下代码:

//截取字符串
        var splitData:String = tv_split_data.text.toString()
        btn_split.setOnClickListener {
            if(splitData.indexOf('_') > 0){
                // split方法我们只要用到一个参数,就是我们要截取的字符,我们将下划线截掉,截取的值用List装起来再toString显示出来
                var strList:List<String> = splitData.split("_")
                tv_split_result.text = strList.toString()
                split_result_lay.visibility = View.VISIBLE
            }
        }


运行效果如下图


20200219152045773.png


现在常用的方法都介绍完毕了,(PS:讲真的,挺繁琐的


3.2字符串模板及拼接


Kotlin格式化字符串,


20200219155124215.png


20200219155220360.png


var str:String = "How Are You"
        btn_format.setOnClickListener { btn_format.text = "你好吗?$str" }


我们可以看到,Kotlin中拼接字符串是很简单的,在$后面跟变量名即可,另外有可能变量会先进行计算,再把运算结果拼接到字符串中,此时需要用大括号把运算表达式给括起来,如下所示

布局文件中加一个按钮

<Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_can_format"
        android:text="计算字符串"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

代码中

var dangerous:String = "dangerous"
        btn_can_format.setOnClickListener { btn_can_format.text = "危险${dangerous.length}" }


在上面的Kotlin代码中,我们频繁用到了 $ ,美元符号,它在Kotlin中属于特殊字符,因此不能直接打印,需要经过转义后方可打印,转义的方法是使用${’***’}表达式,该表达式外层的“ ${‘’} ”为转义声明,内层的“ ** ”为需要原样输出的字符串,如下所示:

写个按钮


<Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_dollar"
        android:text="美元符号"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


代码中

var money:Int = 10
        btn_dollar.setOnClickListener { btn_dollar.text = "美元金额为${'$'}$money" }


还有另一种方式,针对于单个美元符号,如下所示:

btn_dollar.setOnClickListener { btn_dollar.text = "美元金额为\$$money" }


字符串的讲解大致就这些了


四、容器


与Java类似,Kotlin也拥有三类基本的容器,分别是集合Set、队列List、映射Map,然后每类容器又分作只读与可变两种类型,这是为了判断该容器能否进行增、删、改等变更操作,Kotlin对变量的修改操作很慎重,每个变量在定义的时候就必须指定能否修改,比如添加val修饰表示该变量不可修改,添加var修饰表示该变量允许修改。至于容器则默认为只读容器,如果需要允许修改该容器变量,就需要加上Mutable前缀形成新的容器,比如MutableSet表示可变集合,MutableList表示可变队列,MutableMap表示可变映射,只有可变的容器才能够对其内部元素进行增、删、改操作。


既然集合Set、队列List、映射Map三者都属于容器,那么他们必定拥有相同的容器方法,一些公共方法具体说明说下。


isEmpty 判断该容器是否为空。


isNotEmpty 判断该容器是否非空。


clear 清空该容器。


contains 判断该容器是否包含指定元素。


iterator 获取该容器的迭代器。


count 获取该容器包含的元素个数,也可通过size来获取。


另外,Kotlin允许在声明容器变量是就进行初始赋值,这一点在Java中是不行的,当然,不同容器的初始化方法有所不同,如下表所示


kotlin的容器 容器名称 容器的初始化方法
只读集合 Set setOf
可变集合 MutableSet mutableSetOf
只读队列 List listOf
可变队列 MutableList mutableListOf
只读映射 Map mapOf
可变映射 MutableMap mutableMapOf



下面我们逐个来讲解


4.1 集合Set/MutableSet


集合是一种最简单的容器,它有以下特性:


(1)容器内部的元素不按顺序排列,因此无法按照下标进行访问。


(2)容器内部的元素存在唯一性,通过哈希值校验是否存在相同的元素,若存在,则将其覆盖。


因为Set是只读集合,初始化赋值后便不可更改,所以元素变更的方法只适用于可变集合MutableSet,但MutableSet的变更操作尚有以下限制


(1)MutableSet的add方法仅仅在集合中添加元素,由于集合是无序的,因此不知道添加的具体位置。


(2)MutableSet没有修改元素值的方法,一个元素一旦被添加,就不可被修改。


(3)MutableSet的remove方法用于删除指定元素,但无法删除某一个位置的元素,这是因为集合的元素不是按照顺序来排列的。



对于集合的便利操作,Kotlin提供了好几种方式,有熟悉的for - in 循环、迭代器遍历,还有新的面孔forEach,下面一一进行说明


1.for-in循环


示例如下:


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_set_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_set_for"
        android:text="for-in"
        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)
        val goodsMutSet:Set<String> = setOf("小米","华为","荣耀","苹果","OPPO")
        btn_set_for.setOnClickListener {
            var desc = ""
            //使用for-in语句循环取出集合中的每条记录
            for (item in goodsMutSet){
                desc = "${desc}名称:${item}\n"
            }
            tv_set_result.text = "手机畅销品牌如下${goodsMutSet.size}个品牌:\n$desc"
        }
    }
}


运行效果图如下所示:


20200219172238409.png


2.迭代器遍历


迭代器与指针的慨念有点接近,它自身并非具体的元素,二十指向元素的存放地址,所以迭代器遍历其实是遍历所有元素的地址。迭代器通过hasNext方法判断是否存在下一个节点,如果不存在下一节点,就表示已经遍历完毕,他通过next方法获得下一个节点的元素,同时迭代器自身改为指向改元素的地址,下面是代码示例


activity_main.xml中加一个按钮


<Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_set_iterator"
        android:text="迭代器遍历"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


MainActivity.kt


//迭代器遍历
        btn_set_iterator.setOnClickListener {
            var desc = ""
            var iterator = goodsMutSet.iterator()
            //如果迭代器还存在洗一个节点,就继续取出下一个节点的记录
            while (iterator.hasNext()){
                var item = iterator.next()
                desc = "${desc}名称:${item}\n"
            }
            tv_set_result.text = "手机畅销品牌如下${goodsMutSet.size}个品牌:\n$desc"
        }


演示的效果和第一个图相似,


3.forEach遍历


无论是for-in循环还是迭代器遍历,都是Java已有的容器遍历操作,代码书写上不够精炼,对此,Kotlin给容器创造了forEach方法,明确指定该方法就是要依次

遍历容器内部的元素。forEach方法在编码时采用匿名函数的形式,内部用it代表每个元素,下面是运用示例代码:


activity_main.xml添加


<Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_set_foreach"
        android:text="ForEach遍历"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


MainActivity.kt中新增


//forEach遍历
        btn_set_foreach.setOnClickListener {
            var desc = ""
            //forEach内部使用it指代每条记录
            goodsMutSet.forEach { desc = "${desc}名称:${it}\n" }
            tv_set_result.text = "手机畅销品牌如下${goodsMutSet.size}个品牌:\n$desc"
        }


以上关于Set/MutableSet的用法介绍完了,但是我们可以发现在实战中存在很多问题,如下:


(1)集合不允许修改内部元素的值。


(2)集合无法删除指定位置的元素。


(3)不能通过下标获取指定位置的元素。


故而实际开发中基本用不到集合,都是用队列和映射(PS:此时我的内心有一万只羊驼奔腾而过~)


4.2 队列List/MutableList


  队列相对于集合来说的优势就在于有次序,优点如下:
  (1)队列能够通过get方法获取指定位置的元素,也可以直接通过下标获取该位置的元素。
  (2)MutableList的add方法每次都是把元素添加到队列末尾,也可指定添加的位置。
  (3)MutableList的add方法允许替换或者修改指定位置的元素。
  (4)MutableList的removeAt方法允许删除指定位置的元素。
  (5)队列除了拥有跟集合一样的三种遍历方式(for-in循环、迭代器遍历、forEach遍历)外,还多了一种按元素下标循环遍历的方式,示例如下:


布局文件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_list_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_for_index"
        android:text="indices遍历"
        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)
        val goodsMutSet:List<String> = listOf("小米","华为","荣耀","苹果","OPPO","VIVO")
        btn_for_index.setOnClickListener {
            var desc = ""
            //indices是队列的下标数组,如果队列大小为10 ,下标取值 0-9
            for(i in goodsMutSet.indices){
                val item = goodsMutSet[i]
                desc = "${desc}名称:${item}\n"
            }
            tv_list_result.text = "手机畅销品牌如下${goodsMutSet.size}个品牌:\n$desc"
        }
    }
}


20200219180431627.png


MutableList提供了sort系列方法用于给队列中的元素重新排序,其中sortedBy方法表示按照指定条件升序排列,sortByedDescending方法表示按照指定条件降序排列。


4.3 映射Map/MutableMap


映射内部保存的是一组键值对(key-value),也就是说,每个元素都由两个部分构成,第一部分时元素的键,相当于元素的名字;第二部分是元素的值,存放着元素的详细信息。元素的键与值是一一对应的关系,相同键名指向的键值时唯一的,所以映射中每个元素的值各不相同,这个特性使得映射的变更操作与队列存在以下不同之处


(1)映射的containsKey方法判断是否存在指定键名的元素,containsValue方法判断是否存在指定键值的元素。


(2)MutableMap的put方法不单单是添加元素,而是智能的数据存储,每次调用put方法时,映射会先根据键名寻找同名元素,如果找不到就添加新元素,如果找得到就用新元素替换旧元素。


(3)MutableMap的remove方法是通过键名来删除元素的。


(4)调用mapOf和mutableMapOf方法初始化映射时,有两种方式可以表达单个键值对元素,其一是采取“键名 to 键值”的形式,其二是采取Pair配对方式,形如“Pair(键名,键值)”,下面是两种初始化方式的代码示例:

//to方式初始化映射
        var goodsMap:Map<String,String> = mapOf("苹果" to "iPhone",
            "华为" to "Mate20","小米" to "小米10","欧珀" to "OPPO R20", "步步高" to "VIVO X95")
        //Pair方式初始化映射
        var goodsMutMap:MutableMap<String,String> = mutableMapOf(Pair("苹果","iPhone"),
        Pair("华为","Mate20"),Pair("小米","小米10"),Pair("欧珀","OPPO R20"), Pair("步步高","VIVO X95"))


映射的遍历与集合类似,也有for-in循环、迭代器遍历、forEach遍历三种遍历手段。


1.for-in循环


for-in取出来的是映射的元素键值对,若要获取钙元素的键名,还需要访问元素的key属性,若要获取该元素的的键值,还需要访问元素的value属性。下面是在映射中运用for-in循环的代码示例:


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_map_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_map_for"
        android:text="Map_For"
        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 android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //to方式初始化映射
        var goodsMap:Map<String,String> = mapOf("苹果" to "iPhone",
            "华为" to "Mate20","小米" to "小米10","欧珀" to "OPPO R20", "步步高" to "VIVO X95")
        //Pair方式初始化映射
        var goodsMutMap:MutableMap<String,String> = mutableMapOf(Pair("苹果","iPhone"),
        Pair("华为","Mate20"),Pair("小米","小米10"),Pair("欧珀","OPPO R20"), Pair("步步高","VIVO X95"))
        btn_map_for.setOnClickListener {
            var desc = ""
            //使用for-in语句循环取出映射中的每条记录
            for(item in goodsMutMap){
                //item.key 表示该配对的键,item.value 表示该配对的值
                desc = "${desc}厂家:${item.key},名称:${item.value}\n"
            }
            tv_map_result.text = "手机畅销榜包含以下${goodsMutMap.size}款手机:\n$desc"
        }
    }
}


运行效果图

20200221102846312.png


2.迭代器遍历


映射的迭代器通过next函数得到下一个元素,接着需访问该元素的key属性获取键名,访问该元素的value属性获取键值,下面是在映射中运用迭代器遍历的代码示例:


布局中加一个按钮

<Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_map_iterator"
        android:text="Map_iterator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


代码中加一段

btn_map_iterator.setOnClickListener {
            var desc = ""
            val iterator = goodsMutMap.iterator()
            //如果迭代器还存在下一个节点,就继续取出下一个节点的记录
            while (iterator.hasNext()){
                val item = iterator.next()
                desc = "${desc}厂家:${item.key},名称:${item.value}\n"
            }
            tv_map_result.text = "手机畅销榜包含以下${goodsMutMap.size}款手机:\n$desc"
        }


3.forEach遍历


映射的forEach方法内部依旧采用匿名函数的形式,同时把元素的key和value作为匿名函数的输入参数,不过映射的forEach函数需要API24及以上版本支持,开发时注意修改编译配置,下面是在映射中运用forEach遍历的代码示例:


布局文件中增加一个按钮:

<Button
        android:layout_marginTop="20dp"
        android:id="@+id/btn_map_foreach"
        android:text="Map_foreach"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


代码中增加:


btn_map_foreach.setOnClickListener {
            var desc = ""
            //forEach内部使用key指代每条记录的键,使用value指代每条记录的值
            goodsMap.forEach{ key,value -> desc = "${desc}厂家:${key},名称:${value}\n"}
            tv_map_result.text = "手机畅销榜包含以下${goodsMutMap.size}款手机:\n$desc"
        }


运行效果都是一样的,就不贴了,数据类型终于学完了,码字是比较累啊,如有错误请指出,以上内容均为自己一个一个打出来的,没有复制粘贴。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1天前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
105 0
|
1天前
|
存储 Go
Go 浅析主流日志库:从设计层学习如何集成日志轮转与切割功能
本文将探讨几个热门的 go 日志库如 logrus、zap 和官网的 slog,我将分析这些库的的关键设计元素,探讨它们是如何支持日志轮转与切割功能的配置。
128 0
Go 浅析主流日志库:从设计层学习如何集成日志轮转与切割功能
|
1天前
|
SQL 监控 关系型数据库
【MySQL学习】MySQL的慢查询日志和错误日志
【MySQL学习】MySQL的慢查询日志和错误日志
|
1天前
|
监控 Docker 容器
Docker从入门到精通:Docker log 命令学习
了解 Docker 日志管理对容器监控至关重要。`docker logs` 命令用于查看和管理容器日志,例如,`docker logs &lt;container_name&gt;` 显示容器日志,`-f` 或 `--follow` 实时跟踪日志,`--tail` 显示指定行数,`--timestamps` 添加时间戳,`--since` 按日期筛选。Docker 支持多种日志驱动,如 `syslog`,可通过 `--log-driver` 配置。有效管理日志能提升应用程序的稳定性和可维护性。
17 0
|
1天前
|
SQL 关系型数据库 MySQL
MySQL技能完整学习列表11、日志和备份——1、查看日志——2、数据备份和恢复(mysqldump, mysqlbinlog)
MySQL技能完整学习列表11、日志和备份——1、查看日志——2、数据备份和恢复(mysqldump, mysqlbinlog)
49 0
|
1天前
|
Android开发 Kotlin
android开发,使用kotlin学习Fragment
android开发,使用kotlin学习Fragment
54 0
|
1天前
|
Android开发 Kotlin
android开发,使用kotlin学习WorkManager
android开发,使用kotlin学习WorkManager
54 0
|
1天前
|
缓存 Android开发 数据安全/隐私保护
android开发,使用kotlin学习HTTP访问网络
android开发,使用kotlin学习HTTP访问网络
81 0
|
存储 Java
《Kotlin极简教程》第三章 Kotlin基本数据类型
正式上架:《Kotlin极简教程》Official on shelves: Kotlin Programming minimalist tutorial 京东JD:https://item.jd.com/12181725.html 天猫Tmall:https://detail.tmall.com/item.htm?id=558540170670 在 Kotlin 中,所有东西都是对象:数字、字符、布尔和数组。
943 0
|
1天前
|
移动开发 API Android开发
构建高效Android应用:Kotlin协程的实践指南
【5月更文挑战第11天】 在移动开发领域,性能优化和资源管理是至关重要的。特别地,对于Android开发者来说,合理利用Kotlin协程可以极大地改善应用的响应性和稳定性。本文将深入探讨Kotlin协程在Android中的实际应用,包括它们如何简化异步编程模型、提高UI线程的响应性,以及减少内存消耗。我们将通过具体案例分析,了解如何在实际项目中有效地使用协程,从而帮助开发者构建更加高效的Android应用程序。

热门文章

最新文章