Kotlin学习总结(一)——变量、常量、数据类型、条件语句

Kotlin学习总结(一)——变量、常量、数据类型、条件语句

参考博客:Kotlin教程——史上最全面、最详细的学习教程,持续更新中…

一、变量、常量和注解

1.1 变量

kotlin变量的声明方式与Java中声明变量有很大的区别,而且必须使用varval关键字。其中:

  • var: 用此关键字声明的变量表示可变变量,即可读且可写。相当于Java中普通变量
  • val: 用此关键字声明的变量表示不可变变量,即可读且不可写。相当于Java中用final修饰的变量(不是常量)

1.1.1 基础用法

Kotlin学习总结(一)——变量、常量、数据类型、条件语句

类型推断:对于已经生命并赋值的变量,允许你省略类型定义

//立即初始化
var var_a: Int = 10

//推导出类型
var var_b = 5

//没有初始化的时候,必须声明类型
var var_c: Float
var_c = 12.3f
var_c += 1

println("var_a => $var_a \t var_b => $var_b \t var_a => $var_c")

//立即初始化
val val_a: Int = 100

//推导出类型
val val_b = 50

//没有初始化的时候,必须声明类型
val val_c: Int
val_c = 1
// val_c += 1 因为c是常量,所以这句代码是会报错的

println("val_a => $val_a \t val_b => $val_b \t val_c => $val_c")

打印结果为:

var_a => 10 	 var_b => 5 	 var_a => 13.3
val_a => 100 	 val_b => 50 	 val_c => 1
  • 其中。varvalKotlin中定义变量必须使用的关键字。
  • 每一行代码的结束可以省略掉分号;,这一点是和Java不同的地方。当然,第一次写可能会有一点不习惯。
  • print()println()都是打印方法,后者打印完成之后会换一行。此两个方法和Java的打印方法是一模一样的。
  • $符号表示引用的意思。这里理解为字符串模板

1.1.2 在类中声明以及声明可空变量

1.1.2.1 类中声明变量

  • 只有在顶层声明的情况下是可以不用实例化的。
  • 而在一个类中去定义变量,这种情况被称为声明类的属性。
  • 其特点如下:必须初始化,如果不初始化,需使用lateinit关键字。

例:

class Test1{

    // 定义属性
    var var_a : Int = 0
    val val_a : Int = 0

    // 初始化
    init {
        var_a = 10
        // val_a = 0 为val类型不能更改。

        println("var_a => $var_a \t val_a => $val_a")
    }
}

Test1()

输出结果为:

var_a => 10 	 val_a => 0

1.1.2.2 声明可空变量

Kotlin中当我们可以确定这个属性或变量一定不为空时,就用上面的方法定义变量。否则就把它声明为可空变量

可空变量的特点:

  • 在声明的时候一定用标准的声明格式定义。不能用可推断类型的简写。
  • 变量类型后面的?符号不能省略。不然就和普通的变量没区别了。
  • 其初始化的值可以为null或确定的变量值。

定义:

var/val 变量名 : 类型? = null/确定的值

例:

 class Test2{

    // 声明可空变量
    var var_a : Int? = 0
    val val_a : Int? = null

    init {
        var_a = 10
        // val_a = 0 为val类型不能更改。

        println("var_a => $var_a \t val_a => $val_a")
    }
}

Test2()

输出结果为:

var_a => 10 	 val_a => null

1.1.3 后期初始化与延迟初始化

当在类中定义一个变量(属性)的时候是必须初始化的。这在平时的实际开发中能满足大部分的需求。但是还是有一些特殊的场景中不能满足。比如说:Android开发中对组件变量的声明与赋值,以及在使用Dagger2注解变量等。这就需要Kotlin中特有的后期初始化属性来满足这个需求了。当然这里还为大家讲解延迟初始化,在实际的开发中也是很有用处的。

1.1.3.1 后期初始化属性

声明后期初始化属性的特点:

  • 使用lateinit关键字
  • 必须是可读且可写的变量,即用var声明的变量
  • 不能声明于可空变量。
  • 不能声明于基本数据类型变量。例:IntFloatDouble等,注意:String类型是可以的。
  • 声明后,在使用该变量前必须赋值,不然会抛出UninitializedPropertyAccessException异常。

代码示例:

// 声明组件
private lateinit var mTabLayout : TabLayout

lateinit var a : Int // 会报错。因为不能用于基本数据类型。

// 赋值
mTabLayout = find(R.id.home_tab_layout)

// 使用
mTabLayout.setupWithViewPager(mViewPager)

1.1.3.2 延迟初始化属性

所谓延迟初始化即:指当程序在第一次使用到这个变量(属性)的时候在初始化。

声明延迟初始化属性的特点:

  • 使用lazy{}高阶函数,不能用于类型推断。且该函数在变量的数据类型后面,用by链接。
  • 必须是只读变量,即用val声明的变量。

实例讲解:同样是Android中常见的例子

// 声明一个延迟初始化的字符串数组变量
private val mTitles : Array<String> by lazy {
    arrayOf(
            ctx.getString(R.string.tab_title_android),
            ctx.getString(R.string.tab_title_ios),
            ctx.getString(R.string.tab_title_h5)
    )
}

// 声明一个延迟初始化的字符串
private val mStr : String by lazy{
    "我是延迟初始化字符串变量"
}

1.2 Kotlin之常量的用法

Kotlin中声明常量的方式和在Java中声明常量的方式有很大的区别。

Kotlin中使用val时候对应的Java代码:

val numA = 6   //Kotlin中的 
等价于  
public final int numA = 6//Java中的

很显然,Kotlin中只用val修饰还不是常量,它只能是一个不能修改的变量。
那么常量怎么定义呢?其实很简单,在val关键字前面加上const关键字。

即:

const val NUM_A = 6

其特点:const只能修饰val,不能修饰var

声明常量的三种正确方式

  1. 在顶层声明
  2. object修饰的类中声明,在kotlin中称为对象声明,它相当于Java中一种形式的单例类
  3. 在伴生对象中声明

举例说明:

// 1. 顶层声明
const val NUM_A : String = "顶层声明"

// 2. 在object修饰的类中
object TestConst{
    const val NUM_B = "object修饰的类中"
}

// 3. 伴生对象中
class TestClass{
    companion object {
        const val NUM_C = "伴生对象中声明"
    }
}

fun main(args: Array<String>) {
    println("NUM_A => $NUM_A")
    println("NUM_B => ${TestConst.NUM_B}")
    println("NUM_C => ${TestClass.NUM_C}")
}

输出结果为:

NUM_A => 顶层声明
NUM_B => object修饰的类中
NUM_C => 伴生对象中声明

1.3 Kotlin之注释

Kotlin中的注释几乎和Java没什么区别。唯一的区别在于Kotlin中的多行注释中可以嵌套多行注释,而Java中是不能的。

  • 多行注释嵌套

举例:

  /*
    第一层块注释
    /*
        第二层块注释
        /*
            第三层快注释
            这种注释方式在java中是不支持的,但是在kotlin中是支持的。算是一个亮点吧(貌似意义不大)。
         */
     */
 */

二、数据类型

2.1 数值类型

2.1.1 关键字

Kotlin中的数字的内置类型(接近与Java),其关键字为:

  • Byte=> 字节 => 8位
  • Short => 短整型 => 16位
  • Int => 整型 => 32位
  • Long => 长整型 => 64位
  • Float => 浮点型 => 32位
  • Double => 双精度浮点型 => 64位

例:

var a: Byte = 2
var b: Short = 2
var c: Int = 2
var d: Long = 2L         //长整型由大写字母L标记
var e: Float = 2f        //单精度浮点型由小写字母f或大写字符F标记
var f: Double = 2.0
println(" a => $a \n b => $b \n c => $c \n d => $d \n e => $e \n f => $f);   

输出结果为:

a => 2 
b => 2 
c => 2 
d => 2 
e => 2.0 
f => 2.0 

2.1.2 进制数

  • 二进制数
  • 八进制数(Kotlin不支持)
  • 十进制数
  • 十六进制数

例:

var g = 0x0F            //十六进制数
var h = 0b00001011      //二进制数
var k = 123             //十进制数
// ps:Kotlin不支持八进制数
println(" g => $g \n h => $h \n k => $k);   

输出结果为:

g => 15 
h => 11 
k => 123 

2.1.3 数字类型字面常量的下划线

作用:分割数字进行分组,使数字常量更易读

例:

val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

println("oneMillion => $oneMillion")
println("creditCardNumber => $creditCardNumber")
println("socialSecurityNumber => $socialSecurityNumber")
println("hexBytes => $hexBytes")
println("bytes => $bytes")

输出结果为:

oneMillion => 1000000
creditCardNumber => 1234567890123456
socialSecurityNumber => 999999999
hexBytes => 4293713502
bytes => 3530134674

2.1.4 装箱与拆箱

  • 装箱与拆箱

Kotlin中,存在数字的装箱,但是不存在拆箱。因为Kotlin是没有基本数据类型的,Kotlin是万般皆对象的原则。

Kotlin中要实现装箱操作。首先要了解可空引用。即类似Int?(只限数值类型)这样的。

例:

val numValue: Int = 123
//装箱的过程,其实装箱之后其值是没有变化的
val numValueBox: Int? = numValue
println("装箱后: numValueBox => $numValueBox")

输出结果为:

装箱后: numValueBox => 123
  • 两个数值的比较

判断两个数值是否相等(==),判断两个数值在内存中的地址是否相等(===),其实上面的装箱操作之后其内存中的地址根据其数据类型的数值范围而定。

例:

val numValue: Int = 128    
val numValueBox: Int? = numValue

/*
    比较两个数字
 */
var result: Boolean
result = numValue == numValueBox
println("numValue == numValueBox => $result")  // => true,其值是相等的

result = numValue === numValueBox
/*
  上面定义的变量是Int类型,大于127其内存地址不同,反之则相同。
  这是`kotlin`的缓存策略导致的,而缓存的范围是` -128 ~ 127 `。
  故,下面的打印为false
*/
println("numValue === numValueBox => $result")  

输出结果为:

numValue == numValueBox => true
numValue === numValueBox => false

2.1.5 转换

  • 显式转换
    较小的类型不会被隐式转换为更大的类型,故而系统提供了显式转换。提供的显式转换方法如下:
  1. toByte() => 转换为字节型
  2. toShort() => 转换为短整型
  3. toInt() => 转换为整型
  4. toLong() => 转换为长整型
  5. toFloat() => 转换为浮点型
  6. toDouble() => 转换为双精度浮点型
  7. toChar() => 转换为字符型
  8. toString() => 转换为字符串型

例:

var numA: Int = 97
println(numA.toByte())
println(numA.toShort())
println(numA.toInt())
println(numA.toLong())
println(numA.toFloat())
println(numA.toDouble())
println(numA.toChar())
println(numA.toString())

输出结果为:

97
97
97
97.0
97.0
97
a
97
  • 隐式转换

类型是从上下文推断出来的,即算术运算则被重载为适当的转换

例:

// 30L + 12 -> Long + Int => Long
val num = 30L + 12
print(num)

输出结果为:

42

2.2.6 位运算符

Kotlin中对于按位操作,和Java是有很大的差别的。Kotlin中没有特殊的字符,但是只能命名为可以以中缀形式调用的函数,下列是按位操作的完整列表(仅适用于整形(Int)和长整形(Long):

  1. shl(bits) => 有符号向左移 (类似Java<<)
  2. shr(bits) => 有符号向右移 (类似Java>>)
  3. ushr(bits) => 无符号向右移 (类似Java>>>)
  4. and(bits) => 位运算符 and (同Java中的按位与)
  5. or(bits) => 位运算符 or (同Java中的按位或)
  6. xor(bits) => 位运算符 xor (同Java中的按位异或)
  7. inv() => 位运算符 按位取反 (同Java中的按位取反)

例:

 /*
    位运算符
    支持序列如下:shl、shr、ushr、and、or、xor
 */
var operaNum: Int = 4

var shlOperaNum = operaNum shl(2)
var shrOperaNum = operaNum shr(2)
var ushrOperaNum = operaNum ushr(2)
var andOperaNum = operaNum and(2)
var orOperaNum = operaNum or(2)
var xorOperaNum = operaNum xor(2)
var invOperaNum = operaNum.inv()

println("shlOperaNum => $shlOperaNum \n " +
        "shrOperaNum => $shrOperaNum \n " +
        "ushrOperaNum => $ushrOperaNum \n " +
        "andOperaNum => $andOperaNum \n " +
        "orOperaNum => $orOperaNum \n " +
        "xorOperaNum => $xorOperaNum \n " +
        "invOperaNum => $invOperaNum")

输出结果为:

shlOperaNum => 16 
shrOperaNum => 1 
ushrOperaNum => 1 
andOperaNum => 0 
orOperaNum => 6 
xorOperaNum => 6 
invOperaNum => -5 

2.2 布尔类型(Boolean)

Boolean关键字表示布尔类型,并且其值有truefalse

例:

var isNum: Boolean
isNum = false
println("isNum => $isNum")

输出结果为:

isNum => false

2.3 字符型(Char)

1、关键字

Char为表示字符型,字符变量用单引号(‘ ’)表示。并且不能直接视为数字,不过可以显式转换为数字。

例:

var char1: Char
char = 'a'
//char1 = 1        => 这句代码会直接出错
println("char1 => $char1")

输出结果为:

char1 => a

2、显示转换为其他类型

字符型的变量不仅可以转换为数字,同时也可转换为其他类型

例:

var var1 = char1.toByte()
var var2 = char1.toInt()
var var3 = char1.toString()
var var4 = char1.toFloat()
var var5 = char1.toShort()
println("var1 => $var1 \n var2 => $var2 \n var3 => $var3 \n var4 => $var4 \n var5 => $var5")

输出结果为:

var1 => 97 
var2 => 97 
var3 => a 
var4 => 97.0 
var5 => 97

PS:除了可以转换类型外,当变量为英文字母时还支持大小写转换。

例:

/*
   当字符变量为英文字母时,大小写的转换
*/
var charA: Char = 'a'
var charB: Char = 'B'
var charNum: Char = '1'
var result: Char

// 转换为大写
result = charA.toUpperCase() 
println("result => $result")

// 转换为小写
result = charB.toLowerCase()
println("result => $result")

//当字符变量不为英文字母时,转换无效
result = charNum.toLowerCase()
println("result => $result")

输出结果为:

result => A
result => b
result => 1

3、字符转义
Java一样,使用某些特殊的字符时,要使用转义。下列是支持的转义序列:

  • \t => 表示制表符
  • \n => 表示换行符
  • \b => 表示退格键(键盘上的Back建)
  • \r => 表示键盘上的Enter
  • \\ => 表示反斜杠
  • \' => 表示单引号
  • \" => 表示双引号
  • \$ => 表示美元符号,如果不转义在kotlin中就表示变量的引用了
  • 其他的任何字符请使用Unicode转义序列语法。例:’\uFF00’

例:

println("\n  换行符")
println("\t  制表符")
println(" \b  退格键")
println("\r  Enter键同样换行")
println('\\')
println('\'')
println('\"')
println('\$')
println('\uFF01')

输出结果为:

 换行符
     制表符

 退格键
 Enter键同样换行
\
'
"
$
!

2.4 字符串类型(String)

1、关键字

String表示字符串类型。其是不可变的。所以字符串的元素可以通过索引操作的字符:str[index]来访问(字符类型)。可以使用for循环迭代字符串:
其中str[index]中的str为要目标字符串,index为索引

例:

val str: String = "kotlin"
println("str => $str")

//迭代
for (s in str){
    var c : Char = s
    print(c)
    print("\t")
}

输出结果为:

str => kotlin
k	o	t	l	i	n	

2、 字符串字面量

Kotlin中, 字符串字面量有两种类型:

  • 包含转义字符的字符串 转义包括(\t\n等),不包含转义字符串的也同属此类型
  • 包含任意字符的字符串 由三重引号(""" .... """)表示

例:

// 类型1:
var str1: String = "hello\t\tkotlin"
println(str1)
str1 = "hello kotlin"
println(str1)

// 类型2:
val str2 = """ fun main(args: Array<String>){
    println("我是三重引号引用的字符串,我可以包含任意字符")
    } """
println(str2)

输出结果为:

hello		kotlin
hello kotlin
fun main(args: Array<String>){
    println("我是三重引号引用的字符串,我可以包含任意字符")
    } 

PS: 可以使用trimMargin()函数删除前导空格 ,默认使用符号(|)作为距前缀,当然也可以使用其他字符。例:右尖括号(>)、左尖括号(<)等。

例:

val str3: String = """
    > I`m like Kotlin .
    > I`m like Java .
    > I`m like Android .
    > I`m like React-Native.
""".trimMargin(">")
println(str3)

输出结果为:

 I`m like Kotlin .
 I`m like Java .
 I`m like Android .
 I`m like React-Native.

3、字符串模板

使用字符串模板的符号为($)。在$符号后面加上变量名或大括号中的表达式

例:

val text1: String = "我来了!"
var text2: String = "$text1 kotlin"
var text3: String = "$text2 ${text1.length} 哈哈!!!!"
println(text1)
println(text2)
println(text3)

输出结果为:

我来了!
我来了! kotlin
我来了! kotlin 4 哈哈!!!!

2.5 数组型(Array)

  • Kotlin中数组由Array<T>表示,可以去看看源码实现,里面就几个方法
  • 创建数组的3个函数
    1. arrayOf()
    2. arrayOfNulls()
    3. 工厂函数(Array()

1、arrayOf()

创建一个数组,参数是一个可变参数的泛型对象

例:

var arr1 = arrayOf(1,2,3,4,5) //等价于[1,2,3,4,5]
for (v in arr1){
    print(v)
    print("\t")
}

var arr2 = arrayOf("0","2","3",'a',32.3f)
for (v in arr2){
    print(v)
    print("\t")
}

输出结果为:

1	2	3	4	5	
0	2	3	a	32.3	

2、arrayOfNulls()

用于创建一个指定数据类型且可以为空元素的给定元素个数的数组

例:

var arr3 = arrayOfNulls<Int>(3)

//如若不予数组赋值则arr3[0]、arr3[1]、arr3[2]皆为null
for(v in arr3){
    print(v)
    print("\t")
}

println()

//为数组arr3赋值
arr3[0] = 10
arr3[1] = 20
arr3[2] = 30

for(v in arr3){
    print(v)
    print("\t")
}

输出结果为:

null	null	null	
10	20	30	

3、工厂函数

  • 使用一个工厂函数Array(),它使用数组大小和返回给定其索引的每个数组元素的初始值的函数。
  • Array() => 第一个参数表示数组元素的个数,第二个参数则为使用其元素下标组成的表达式

例:

var arr4 = Array(5,{index -> (index * 2).toString() })
for (v in arr4){
    print(v)
    print("\t")
}

输出结果为:

0	2	4	6	8

4、原始类型数组

  • Kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:
    1. ByteArray => 表示字节型数组
    2. ShortArray => 表示短整型数组
    3. IntArray => 表示整型数组
    4. LongArray => 表示长整型数组
    5. BooleanArray => 表示布尔型数组
    6. CharArray => 表示字符型数组
    7. FloatArray => 表示浮点型数组
    8. DoubleArray => 表示双精度浮点型数组
  • PS: Kotlin中不支持字符串类型这种原始类型数组,可以看源码Arrays.kt这个类中并没有字符串数组的声明。而源码中StringArray.kt这个类并不是声明字符串型数组的。

下面的例子只演示了几种,其他的类似。
例:

var intArr: IntArray = intArrayOf(1,2,3,4,5)
for (number in intArr){
    print(number)
    print("\t")
}

println()

var charArr: CharArray = charArrayOf('a','1','b','c','3','d')
for (char in charArr){
    print(char)
    print("\t")
}

println()

var longArr: LongArray = longArrayOf(12L,1254L,123L,111L)
for (long in longArr){
    print(long)
    print("\t")
}

输出结果为:

1	2	3	4	5	
a	1	b	c	3	d	
12	1254   123	111	

三、条件语句

3.1 if语句

Kotlin中的if语句和Java还是还是有一定的区别的,它能在Java中更灵活,除了能实现Java写法外,还可以实现表达式(实现三元运算符),及作为一个块的运用。

1、传统写法(同Java写法一样)

例:

var numA = 2
if (numA == 2){
    println("numA == $numA => true")
}else{
    println("numA == $numA => false")
}

输出结果为:

numA == 2 => true

2、Kotlin中的三元运算符

  • 在Kotlin中其实是不存在三元运算符(condition ? then : else)这种操作的。
  • 那是因为if语句的特性(if表达式会返回一个值)故而不需要三元运算符。

例:

// 在Java中可以这么写,但是Kotlin中直接会报错。
// var numB: Int = (numA > 2) ? 3 : 5

// kotlin中直接用if..else替代。例:
var numB: Int = if ( numA > 2 ) 3 else 5  // 当numA大于2时输出numB的值为3,反之为5
println("numB = > $numB")

输出结果为:

numB = > 3

由上可以看出,Kotlin中的if可以作为一个表达式并返回一个值。

3、作为一个块结构,并且最后一句表达式为块的值

例:

var numA: Int = 2
var numC: Int = if (numA > 2){
    numA++
    numA = 10
    println("numA > 2 => true")
    numA
}else if (numA == 2){
    numA++
    numA = 20
    println("numA == 2 => true")
    numA
}else{
    numA++
    numA = 30
    println("numA < 2 => true")
    numA
}

// 根据上面的代码可以看出,每一个if分支里面都是一个代码块,并且返回了一个值。根据条件numC的值应该为20
println("numC => $numC")

输出结果为:

numA == 2 => true
numC => 20

3.2 for语句

  • Kotlin废除了Java中的for(初始值;条件;增减步长)这个规则。但是Kotlin中对于for循环语句新增了其他的规则,来满足刚提到的规则。
  • for循环提供迭代器用来遍历任何东西
  • for循环数组被编译为一个基于索引的循环,它不会创建一个迭代器对象

1、新增的规则,去满足for(初始值;条件;增减步长)这个规则

  • 1.1、递增

关键字:until
范围:until[n,m) => 即大于等于n,小于m

例:

  // 循环5次,且步长为1的递增
  for (i in 0 until 5){
    print("i => $i \t")
  }

输出结果为

i => 0 	i => 1 	i => 2 	i => 3 	i => 4
  • 1.2、递减
  • 关键字:downTo
  • 范围:downTo[n,m] => 即小于等于n,大于等于m ,n > m

例:

// 循环5次,且步长为1的递减
for (i in 15 downTo 11){
    print("i => $i \t")
}

输出结果为:

i => 15 	i => 14 	i => 13 	i => 12 	i => 11 	

1.3、符号(' .. ') 表示递增的循环的另外一种操作

  • 使用符号( '..').
  • 范围:..[n,m]=> 即大于等于n,小于等于m
  • until的区别,一是简便性。二是范围的不同。

例:

print("使用 符号`..`的打印结果\n")
for (i in 20 .. 25){
    print("i => $i \t")
}

println()

print("使用until的打印结果\n")
for (i in 20 until 25){
    print("i => $i \t")
}

输出结果为:

使用 符号`..`的打印结果
i => 20 	i => 21 	i => 22 	i => 23 	i => 24 	i => 25 	
使用until的打印结果
i => 20 	i => 21 	i => 22 	i => 23 	i => 24 

1.4、设置步长

关键字:step

例:

for (i in 10 until 16 step 2){
    print("i => $i \t")
}

输出结果为:

i => 10 	i => 12 	i => 14 

2、迭代

  • for循环提供一个迭代器用来遍历任何东西。
  • for循环数组被编译为一个基于索引的循环,它不会创建一个迭代器对象

2.1、遍历字符串

例:

for (i in "abcdefg"){
    print("i => $i \t")
}

输出结果为:

i => a 	i => b 	i => c 	i => d 	i => e 	i => f 	i => g 	

2.2、遍历数组

例:

var arrayListOne = arrayOf(10,20,30,40,50)
for (i in arrayListOne){
    print("i => $i \t")
}

输出结果为:

i => 10 	i => 20 	i => 30 	i => 40 	i => 50 	

2.3、使用数组的indices属性遍历

例:

var arrayListTwo = arrayOf(1,3,5,7,9)
for (i in arrayListTwo.indices){
    println("arrayListTwo[$i] => " + arrayListTwo[i])
}

输出结果为:

arrayListTwo[0] => 1
arrayListTwo[1] => 3
arrayListTwo[2] => 5
arrayListTwo[3] => 7
arrayListTwo[4] => 9

2.4、使用数组的withIndex()方法遍历

例:

var arrayListTwo = arrayOf(1,3,5,7,9)
for ((index,value) in arrayListTwo.withIndex()){
    println("index => $index \t value => $value")
}

输出结果为:

index => 0 	 value => 1
index => 1 	 value => 3
index => 2 	 value => 5
index => 3 	 value => 7
index => 4 	 value => 9

2.5、使用列表或数组的扩展函数遍历

  • 数组或列表有一个成员或扩展函数iterator()实现了Iterator<T>接口,且该接口提供了next()hasNext()两个成员或扩展函数
  • 其一般和while循环一起使用
  1. 可以查看Array.kt这个类。可以看见其中的iterator()函数,而这个函数实现了Iterator接口。

     /**
       *   Creates an iterator for iterating over the elements of the array.
       */
     public operator fun iterator(): Iterator<T>
    
  2. 查看Iterator.kt这个接口类,这个接口提供了hasNext()函数和next()函数。

     public interface Iterator<out T> {
    
     /**
       * Returns the next element in the iteration.
       */
     public operator fun next(): T
    
     /**
       * Returns `true` if the iteration has more elements.
       */
     public operator fun hasNext(): Boolean
     }
    

例:

var arrayListThree = arrayOf(2,'a',3,false,9)
var iterator: Iterator<Any> = arrayListThree.iterator()

while (iterator.hasNext()){
    println(iterator.next())
}

输出结果为:

2
a
3
false
9

3.3 when语句

Kotlin中使用when语句替代掉switch语句,而且比switch语句更加强大

  1. when语句实现switch语句功能

    例:

    when(5){
        1 -> {
            println("1")
        }
        2 -> println("2")
        3 -> println("3")
        5 -> {
            println("5")
        }
        else -> {
            println("0")
        }
    }
    

    输出结果为:

    5
    
  2. 和逗号结合使用,相当于switch语句中的不使用break跳转语句

    例:

    when(1){
         // 即x = 1,2,3时都输出1。
        1 , 2 , 3 -> {
            println("1")
        }
        5 -> {
            println("5")
        }
        else -> {
            println("0")
        }
    }
    

    输出结果为:

    1
    
  3. 条件可以使用任意表达式,不仅局限于常量

    相当于if表达式的用法。

    例:

    var num:Int = 5
    when(num > 5){
        true -> {
            println("num > 5")
        }
        false ->{
            println("num < 5")
        }
        else -> {
            println("num = 5")
        }
    }
    

    输出结果为:

    num < 5
    
  4. 检查值是否存在于集合或数组中

    • 操作符:
      1. (in)
      2. (!in) 不在
    • 限定:只适用于数值类型

    例:

    var arrayList = arrayOf(1,2,3,4,5)
    when(1){
        in arrayList.toIntArray() -> {
            println("1 存在于 arrayList数组中")
        }
        in 0 .. 10 -> println("1 属于于 0~10 中")
        !in 5 .. 10 -> println("1 不属于 5~10 中")
        else -> {
            println("都错了 哈哈!")
        }
    }
    

    输出结果为:

    1 存在于 arrayList数组中
    

    其中,符号( .. )表示的意思。如例子中的0 .. 10就表示0至10或者0到10

  5. 检查值是否为指定类型的值

    • 操作符
      1. (is)
      2. 不是(!is)
    • 值得注意的是,Kotlin的智能转换可以访问类型的方法和属性

    例:

    when("abc"){
        is String -> println("abc是一个字符串")
        else -> {
            println("abc不是一个字符串")
        }
    }
    
    // 智能转换
    var a: Int = 2
    when(a){
        !is Int -> {
            println("$a 不是一个Int类型的值")
        }
        else -> {
            a = a.shl(2)
            println("a => $a")
        }
    }
    

    输出结果为:

    abc是一个字符串
    a => 8
    
  6. 不使用表达式的when语句

    表示为最简单的布尔表达式

    例:

    var array = arrayOfNulls<String>(3)
    when{
         true -> {
             for (i in array){
                 print(" $i \t")
             }
             println()
         }
         else -> {
    
         }
    }
    

    输出结果为:

     null 	 null 	 null 
    

when和if else一样,也返回值

上一篇:linux中的NUMA配置


下一篇:x86服务器虚拟化的资源划分和性能优化