Kotlin学习(一):数据类型

一基本数据类型

Kotlin的基本数据类型跟java高级语言一样,包括整型,长整型,浮点型,双精度,布尔型,字符型,字符串这几种常见类型。

1.1Kotlin和Java的基本数据类型的对比
基本数据类型名称 Kotlin的数据类型 Java的数据类型
整型 Int int 和 Integer
长整型 Long long和Long
浮点型 Float float和Float
双精度 Double double和Double
布尔型 Boolean boolean和Boolean
字符型 Char char
字符串 String String
1.2变量的声明

格式:var 变量名:变量类型
例如: var i:Int =0;至于后面的分号,则看代码行后面是否还有其他语句,如果变量声明完毕直接回车换行,那么后面无需带分号;如果没有回车换行,而是添加其他语句,那么变量声明语句要带上分号

1.3变量之间的转换

Kotlin变量的另一个重要特点是类型转换,在Java开发中,如int、 long、 float、 double类型的变量可以直接在变量名前面加上诸如(int) 、(long) 、(float)、(double) 这种表达式进行强制类型转换;对于int (整型)和char (字符型)这两种类型,甚至都无须类型,只能调用类型转换函数输出其他类型的变量,表2-2是常见的几种类型转换函数的说明。.

Kotlin的数据类型转换函数 转换函数说明
toInt 转换为整型数
toLong 转换为长整型
toFloat 转换为浮点数
toDouble 转换为双精度数
toChar 转换为字符
toString 转换为字符串
        val origin: Float = 65f;
        tv_string.text = origin.toString()

        var int: Int;
        int = origin.toInt();
        tv_integer.text = int.toString();

        var long: Long;
        long = origin.toLong()
        tv_long.text = long.toString()

        var double: Double
        double = origin.toDouble();
        tv_double.text = double.toString()

        var boolean: Boolean
        boolean = origin.isNaN()
        tv_boolean.text = boolean.toString()

        var char: Char
        char = origin.toChar()
        tv_char.text = char.toString()

注意到上述类型转换代码的第一行变量声明语句以val开头,而其余的变量声明语句均以var开头,这是为什么呢?其实val和var的区别在于,前者修饰过的变量只能在第一次声明时赋值,后续不能再赋值;而后者修饰过的变量在任何时候都允许赋值。方便记忆的话,可以把val看作是Java里的final关键字;至于var, Java里面没有对应的关键字,就当它是例行公事好了。

二:数组

2.1数组变量的声明

java中声明一个整型数组如下:
int[] int_array=new int[]{1,2,3,4};
其他的类型只要把int替换成long,float,double,boolean,char,其中之一即可。
但是在Kotlin中,声明并初始化一个整型数组是下面这样的:
var int_array:IntArray= intArrayOf(1,2,3,4)
Kotlin与Java之间的区别:

  • Kotlin另外提供了新的整型数组类型,即IntArray
  • 分配一个常量数组,Kotlin调用的是intArrayOf方法,并不使用new关键字
    其他的基本数组类型:
Kotlin的基本数组类型 数组类型的名称 数组类型的初始化方法
整型数组 IntArray intArrayOf
长整型数组 LongArray longArrayOf
浮点型数组 FloatArray floatArrayOf
双精度数组 DoubleArray doubleArrayOf
布尔类型数组 BooleanArray booleanArrayOf
字符数组 CharArray charArrayOf

不知读者有没有注意到,上面的Kotlin数组类型不包括字符串数组,而Java是允许使用字符串数组的,声明字符串数组的Java代码示例如下:
String[] string_array=new String[]{"how","are","you"}但在Kotlin这里,并不存在名为StringArray的数组类型,因为String是一种特殊的基 本数据类型。要想在Kotlin中声明字符串数组,得使用Array<String>类型,也就是把“String"”用尖括号包起来。同时,分配字符串数组的方法也相应变成了arrayOf,下面是声明字符串数组的Kotlin代码:这种字符串数组的声明方式是不是很熟悉?看起来就跟Java里面的ArrayList用法差不多,都是在尖括号中间加入数据结构的类型。同理,其他类型的数组变量也能通.过“Array<数据类型>”的方式来声明,像前面介绍的整型数组,其实可以使用类型Array<Int>,以此类推,改造之后的各类型数组变量的声明代码如下所示:

var int_ array :Array<Int> = array0f(1, 2, 3)
var long_ array :Array<Long> = array0f(1, 2,3)
var float_ array : Array<F1oat> = array0f(1.0f, 2.0f, 3.0f)
var double_ array: Array<Doub1e> = array0f(1.0, 2.0,3.0)
var boolean_ array : Array<Boolean> = arrayOf(true, false, true)
var char_ array :Array<Char> = arrayOf('a', 'b', 'c')
  class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
      
        //声明整型数组
        var int_array: IntArray = intArrayOf(1, 2, 3, 4);
        //也可以按下面方式声明
        var int_array2: Array<Int> = arrayOf(1, 2, 3, 4)
        tv_integer.setOnClickListener { setArrayStr(int_array2) }

        //声明长整型数组
        var long_array: LongArray = longArrayOf(1, 2, 3);
        var long_array2:Array<Long> = arrayOf(1, 2, 3)
        tv_long.setOnClickListener { setArrayStr(long_array2) }

        //声明浮点数组
        var float_array: FloatArray = floatArrayOf(1.0f, 2.0f, 3.0f);
        var float_array2:Array<Float> = arrayOf(1.0f, 2.0f, 3.0f)
        tv_float.setOnClickListener { setArrayStr(float_array2) }

        //声明双精度数组
        var double_array: DoubleArray = doubleArrayOf(1.0, 2.0, 3.0);
        var double_array2:Array<Double> = arrayOf(1.0, 2.0, 3.0)
        tv_double.setOnClickListener { setArrayStr(double_array2) }

        //声明布尔型数组
        var boolean_array: BooleanArray = booleanArrayOf(false, true, false);
        var boolean_array2:Array<Boolean> = arrayOf(false, true, false)
        tv_boolean.setOnClickListener {
            var str:String = ""
            for (item in boolean_array2) {
                str = str + item.toString() + ", "
            }
            tv_text.text = str }

        //声明字符数组
        var char_array: CharArray = charArrayOf('a', 'b', 'c');
        var char_array2:Array<Char> = arrayOf('a', 'b', 'c')
        tv_char.setOnClickListener {  var str:String = ""
            for (item in char_array) {
                str = str + item.toString() + ", "
            }
            tv_text.text = str }

        //声明字符串数组
        var string_array: Array<String> = arrayOf("hao", "are", "you");
        tv_string.setOnClickListener {
            var str:String = ""
            var i:Int = 0
            while (i<string_array.size) {
                str = str + string_array[i] + ", "
                //数组元素可以通过下标访问,也可通过get方法访问
                //str = str + string_array.get(i) + ", "
                i++
            }
//            for (item in string_array) {
//                str = str + item + ", "
//            }
            tv_text.text = str
        }


    }

    inline fun <reified T : Number> setArrayStr(array: Array<T>) {
        var str: String = ""
        for (item in array) {
            str = str + item.toString() + ",";
        }
        tv_text.text = str
    }
}

2.2数组元素的操作

  • (1)对于如何获取数组长度,Java使用.length,而Kotlin使 用size
  • (2)对于如何获取指定位置的数组元素,Java通过方括号加下标来获取,比如"int_ array[0]"指的是得到该数组的第一个元素 ; Kotlin也 能通过方括号加下标来获取指定元素,不过Kotlin还拥有get和set两个方法,通过get方法获取元素值,通过set方法修改元素值,看起来就像在操作ArrayList队列。
 var str_array: Array<String> = arrayOf("how", "are", "you")
        btn_shuzu.setOnClickListener {
            var str: String = ""
            var i: Int = 0
            while (i < str_array.size) {
                str = str + str_array[i] + ","
                //数组元素可以通过下标访问,也可以通过get方法访问
                //str=str+str_array.get(i)
                i++
            }
            btn_shuzu.text = str
        }

2.3 字符串

2.3.1 字符串与基本类型的转换

首先要说明的是字符串类型与基本变量类型之间的转换方式,在前面的“2.1.2简单变量之间的转换”中,提到基本数据类型的变量可以通过toString方法转换为字符串类型。反过来,字符串类型又该如何转换为基本变量类型呢?表2-4展示使用Kotlin和Java编码将字符串转换为基本数据类型的对照方式说明。

符串转换目标 Koin的转换方式 Java的转换方式
字符串转整型 字符串变量的toInt方法 Integer.parseInt (字符串变量)
字符串转长整型 字符串变量的toLong方法 Long.parseLonglogpsuong (字符串变量)
字符串转浮点数 字符串变量的toFloat方法 Float.parseFloat(字符串变量)
字符串转双精度数 字符串变量的toDouble方法 Double.parseDouble(字符串变量)
字符串转布尔类型 字符串变量的toBoolean方法 Double.parseBoolean(字符串变量)
字符串转字符数组 字符串变量的toCharArray方法 字符串变量的toCharArray方法

2.3.2字符串的常用方法

当然,转换类型只是字符串的基本用法,还有更多处理字符串的其他用法,比如查找子串、替换子串、截取指定位置的子串、按特定字符分隔子串等,在这方面Kotlin基本兼容Java的相关方法。对于查找子串的操作,二者都调用indexOf方法;对于截取指定位置子串的操作,二者都调用substring方法;对于替换子串的操作,二者都调用replace方法;对于按特定字符分隔子串的操作,二者都调用split方法。

//2.3.2字符串的常用方法
        //查找子串indexOf、截取指定位置子串substring()、替换子串replace()、分隔子串split()、
        var origin_str: String = "123456.789"
        if (origin_str.indexOf('.') > 0) {
            btn_str.text = origin_str.substring(0, origin_str.indexOf('.'))

        }

        //注意:split()方法返回的时队列,即List<String>
        btn_split.setOnClickListener {
            var strList: List<String> = origin_str.split('.')
            var strResult: String = ""
            for (item in strList) {
                strResult = strResult + item + ","
            }
            btn_split.text = strResult
        }

//获取指定位置的字符串
        btn_get_char.setOnClickListener {
            btn_get_char.text = origin_str.get(3).toString()
        }

2.3.3 字符串模板及其拼接

kotlin进行了优化,何必引入这些麻烦的格式转换符呢?直接在字符串中加入“$变量名”即可表示此处引用该变量的值,岂不妙哉!
例如:

     //2.3.3字符串模板及其拼接
       var origin: String = "123456.789"
       //模板
       btn_format.setOnClickListener { btn_format.text = "字符串模板为:$origin" }

这里要注意,符号$后面跟变量名,系统会自动匹配最长的变量名。比如下面这行代码,打印出来的是变量origin_str的值,而不是origin的值:
例如:

  //2.3.3字符串模板及其拼接
        var origin_str: String = "123456.789"
        //模板
        btn_format.setOnClickListener { btn_format.text = "字符串模板为:$origin_str" }

另外,有可能变量会先进行运算,再把运算结果拼接到字符串中。此时,需要用大括号把运算表达式给括起来,具体代码如下所示:

//模板带有计算
 btn_format_caculate.setOnClickListener { btn_format_caculate.text = "字符串长度为:${origin_str.length}" }
在上述的Kotlin格式化代码中,美元符号$属于特殊字符,因此不能直接打印它,必须经过转义才可以打印。转义的办法是使用“${'***'}”表达式,
该表达式外层的"${'*** '}"为转义声明,
内层的“***”为需要原样输出的字符串,所以通过表达式“${$'}”即可打印一个美元符号,示例代码如下:
 "${'***'}" 打印一个转义字符 -->"${'$'}"--即打印一个$符号
 btn_dollar.setOnClickListener { btn_dollar.text = "美元符号:${'$'}$origin" }

2.4 容器

2.4.1 容器的基本操作

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

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

  • isEmpty:
  • isNotEmpty:
  • clear:
  • contains:
  • iterator:
  • count:获取容器包含的元素的个数,也可以通过size属性获取元素数量
    另外,Kotlin允许在声明容器变量时就进行初始赋值,例如:
 val satelLites: List<String> = listOf("水星", "金星", "地球", "火星", "木星", "土星")

当然,不同容器的初始化方法有所区别,各种容器与其初始化方法的对应关系见表2-5。

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

2.4.2 集合Set/MutableSet

集合是一种最简单的容器,它具有以下特性:
(1)容器内部的元素不按顺序排列,因此无法按照下标进行访问。
(2)容器内部的元素存在唯- -性,通过哈希值校验是否存在相同的元素,若存在,则将其覆盖。
因为Set是只读集合,初始化赋值后便不可更改,所以元素变更的方法只适用于可变集合MutableSet,但MutableSet的变更操作尚有以下限制:
(1) MutableSet的add方 法仅仅往集合中添加元素,由于集合是无序的,因此不知道添加的具体位置。
(2) MutableSet没 有修改元素值的方法,一个元素一旦被添加,就不可被修改。
(3) MutableSet的remove方 法用于删除指定元素,但无法删除某个位置的元素,这是因为集合内的元素不是按顺序排列的。
对于集合的遍历操作,Kotlin提供了好几种方式,有熟悉的for-in循环、迭代器遍历,还有新面孔forEach遍历,这三种集合遍历的用法说明如下。

for-in循环
 val goodsMutSet: Set<String> = setOf("iphone11", "Mate30", "小米9", "oppo11", "VIVO", "魅族17")
        btn_set_for.setOnClickListener {
            var desc = ""
            for (item in goodsMutSet) {
                desc = "${desc}名称:${item}\n"
            }
            btn_set_for.text = "手机畅销榜包含以下${goodsMutSet.size}手机:\n$desc"
        }
Iterator遍历
    btn_iterator.setOnClickListener {
            var desc = ""
            val iterator = goodsMutSet.iterator()
            while (iterator.hasNext()) {
                val item = iterator.next()
                desc = "${desc}名称:${item}\n"
            }
            btn_iterator.text = "手机畅销榜包含以下${goodsMutSet.size}手机:\n$desc"
        }
forEach遍历
   btn_forEach.setOnClickListener {
            var desc = ""
            goodsMutSet.forEach {
                desc = "${desc}名称:${it}\n"
                btn_forEach.text = "手机畅销榜包含以下${goodsMutSet.size}手机:\n$desc"
            }
        }

结合以上有关SetMutableSet的用法说明,可以发现集合在实战中存在诸多不足,主要包括以下几点:
(1) 集合不允许修改内部元素的值。
(2)集合无法删除指定位置的元素。
(3) 不能通过下标获取指定位置的元素。

2.4.3 队列List/MutableList

队列是一种元素之间按照顺序排列的容器,它与集合的最大区别在于多了次序管理。不要小看这个有序性,正因为队列建立了秩序规则,所以它比集合多提供了如下功能(注意,凡是涉及增、删、改的,都必须由MutableList来完成) :

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


        val goodsMutList: List<String> = listOf("iphone11", "Mate30", "小米9", "oppo11", "VIVO", "魅族17")
        btn_list_forin.setOnClickListener {
            var desc = ""
            //indices是队列的下标数组。如果队列大小为10,下标数组的取值为0-9
            for (i in goodsMutList.indices) {
                val item = goodsMutList[i]
                desc = "${desc}名称:${item}\n"
            }
            btn_list_forin.text = "手机畅销榜包含以下${goodsMutList.size}手机:\n$desc"
        }

(6) MutableList提 供了sort系列方法用于给队列中的元素重新排序,其中sortBy方法表示按照指定条件升序排列,sortByDescending方 法表示按照指定条件降序排列。下 面是一个给队列排序的代码例子(含升序和降序) :

        var sortAsc = true
        btn_list_sort.setOnClickListener {
            //

            if (sortAsc) {
                goodsMutList.sortedBy { it.length }
            } else {
                goodsMutList.sortedByDescending { it.length }
            }

            var desc = ""
            for (item in goodsMutList) {
                desc = "${desc}名称:${item}\n"
            }
            btn_list_sort.text = "手机畅销榜已按照${if (sortAsc) "升序" else "降序"}重新排序:\n$desc"

            sortAsc = !sortAsc
        }

2.4.4 映射Map/MutableMap

映射内部保存的是一组键值对(Key-Value) ,也就是说,每个元素都由两部分构成,第一部分 是元素的键,相当于元素的名字:第二部分是元素的值,存放着元素的详细信息。元素的键与值是一一对应的关系,相同键名指向的键值是唯一的, 所以映射中每个元素的键名各不相同,这个特性使得映射的变更操作与队列存在以下不同之处(注意,增、删操作必须由MutableMap来完成) :
(1)映射的containsKey方法判断是否存在指定键名的元素,containsValue方法判断是否存在指定键值的元素。
(2) MutableMap的put方 法不单单是添加元素,而是智能的数据存储。每次调用put方法时,映射会先根据键名寻找同名元素,如果找不到就添加新元素,如果找得到就用新元素替换旧元素。
(3) MutableMap的remove方 法是通过键名来删除元素的。
(4)调用mapOf和mutableMapOf方 法初始化映射时,有两种方式可以表达单个键值对元素,其一是采取“键名to键值”的形式,其二是采取Pair配对方式,形如“Pair(键名,键值)”。下面是这两种初始化方式的代码例子:

 //初始化
        //1.to方式映射
        var goodMap: Map<String, String> =
            mapOf("苹果" to "iphone11", "华为" to "huawei30", "小米" to "xiaomi9", "欧珀" to "OPPO", "魅族" to "meizu16")

        //2.Pair方式初始化映射
        var goodsMutMap: MutableMap<String, String> = mutableMapOf(
            Pair("苹果", "iphone11"),
            Pair("华为", "mate30"), Pair("欧珀", "OPPO"), Pair("小米", "xiaomi6"), Pair("魅族", "meizu16")
        )

映射的遍历与集合类似,也有for-in循环、迭代器遍历、forEach遍 历三种遍历手段。但是由于映射的元素是一一个键值对,因此它的遍历方式与集合稍有不同,详述如下:

for-in
    btn_map_forIn.setOnClickListener {
            var desc = ""
            //使用for-in语句循环取出映射中的每条记录
            for (item in goodsMutMap) {
                //item.key表示该配对的键,即厂家名称;item.value表示该配对的值,即手机名称
                desc = "${desc}厂家;${item.key},名称:${item.value}\n"
            }
            btn_map_forIn.text = "手机畅销榜包含以下${goodsMutMap.size}款手机:\n$desc"
        }
迭代器遍历
btn_map_iterator.setOnClickListener {
            var desc = ""
            val iterator = goodsMutMap.iterator()
            while (iterator.hasNext()) {
                val item = iterator.next()
                desc = "${desc}厂家;${item.key},名称:${item.value}\n"
            }
            btn_map_iterator.text = "手机畅销榜包含以下${goodsMutMap.size}款手机:\n$desc"
        }
forEach遍历
btn_map_forEach.setOnClickListener {
            var desc = ""
            goodMap.forEach { key, value ->
                desc = "${desc}厂家;${key},名称:${value}\n"
            }
            btn_map_forEach.text = "手机畅销榜包含以下${goodsMutMap.size}款手机:\n$desc"
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容