循环迭代和参数匹配等内容永远是一个编程语言中最基础也是重要的内容,Kotlin中的迭代和Java中的迭代还是有区别的,本文主要将介绍Kotlin中如何进行外部迭代,循环和参数匹配的内容。
Kotlin中新增了一个范围类,其实这一点和其他高级语言很像(比如Matlab中的一维矩阵循环),使用专门类来对某一个范围里的值进行遍历,我们用…符号来构建范围,比如说:
val range = 1..5
这段代码就创建了一个从1到5的范围类,除此之外,我们也可以对字符进行迭代,比如:
val cRange = 'a'..'e'
这段代码创建的是一个从a字母遍历到e字母的范围。
范围类甚至可以不局限于像int,long,character这样的基元,对于像String这样的引用类型也可以使用迭代比如说:
val sRange = "help".."helz"
val isin = sRange.contains("help")
println(isin)
这里我们先创建了一个范围是从help到helz的范围,具体来说就是从help,helq,helr…就是改变最后一个字母,依次往下迭代。最终会发现输出的是true,说明help在范围中,也可以发现在这个范围默认是一个闭区间。
接下来介绍具体在Kotlin中进行特定迭代的方法。
一旦确定了一个范围,就可以使用for语句进行范围的迭代,比如我们遍历上面的提到的范围,看看输出的内容是什么:
fun main() {
val range = 1..5
val cRange = 'a'..'e'
val sRange = "help".."helz"
val isin = sRange.contains("help")
//println(isin)
for(s in cRange){
println(s)
}
}
这里对字符的范围类进行了迭代然后输出,最后输出的结果为:
可以看到已经对该范围进行了遍历,对于数字范围或者其他基元范围对象也可以进行该遍历。但是对于非基元的范围对象,比如说上面提到的sRange,它的类型实际上是CloseRange< T >,这个类型是没有iterator的迭代方法的,我们也可以尝试输入,可以得到以下结果:
如果我们想要对该类范围也进行for语句迭代,我们可能需要继承这个范围类然后重写iterator方法。
前面提到了正向迭代,但是如果我们想进行反向迭代该怎么做呢,比如我们想从5遍历到1怎么办呢?我们可以试试创建一个5…1的范围,但是会是以下的结果:
可以看到,这样创建出来的范围的范围是5 <= x <= 1 ,显然这范围是无效的。这种时候我们就需要使用到downTo运算符,如果说 … 运算符创建的范围是5 <= x <= 1,那么downTo运算符的范围就是5 >= x >= 1,这样就创建出了反向迭代的范围:
具体来说,对downTo方法的调用创建类IntProgression的一个实例,它也是Kotlin.ranges包里的一个部分。
需要说明的是无论是…还是downTo方法(或者中缀运算符),它们创建的都是一个左右都闭合的区间,即它是包含两个边界值的。
上面提到的两个运算符创建的都是左闭右闭的区间,那如果我们想创建开区间或者想要跳过范围内的某些值呢?第一个利用until运算符就可以创建一个左闭右开的区间:
这里就创建了一个从一到五,左闭右开的区间。
这里介绍的第二个方法就是设置遍历步长,我们范围的默认步长是1,也就是每次增长1,如果我们要设置遍历步长就要用到step关键字,比如说:
val untilRange = 1 until 5 step 2
我们输出这个范围,得到的结果是:
第三个方法就是使用filter方法对范围内的值进行一些过滤,比如我们如果想要筛选出所有可以被3和5整除的值就可以使用filter方法:
val range = 1..100
for(s in range.filter { it%3 == 0 && it%5 == 0 }){
println(s)
}
这里的it代表的就是迭代中的当前值,具体输出值就是:
在Kotlin中创建数组要比Java中简单,使用arrayOf方法可以创建数组:
val array1 = arrayOf(1,2,3,4,5)
这样就创建了一个Int类型的数组,如果我们想要创建一个int类型的数组那要使用intArrayOf方法,我们可以对比一下,使用一下代码:
val array1 = arrayOf(1,2,3,4,5)
val array2 = intArrayOf(1,2,3,4,5)
println(array1[0].javaClass)
println(array2[0].javaClass)
可以得到结果:
可以看到第一个结果是Integer类型的数组,第二个是int类型的数组。
在Kotlin中创建列表使用listOf方法即可:
val list1 = listOf(1,2,3,4,5)
如果我们想要遍历数组或者列表,那使用到的方法其实是和前面对范围的遍历是类似的,我们使用for语句进行迭代:
val array1 = arrayOf(1,2,3,4,5)
val array2 = intArrayOf(1,2,3,4,5)
val list1 = listOf(1,2,3,4,5)
println(array1[0].javaClass)
println(array2[0].javaClass)
for (x in array1){
println(x)
}
for (y in list1){
println(y)
}
其实在之前也提到过,这个for循环就是用到了iterator方法,有iterator方法的类就可以进行for迭代。
但是在数组或者列表中进行迭代时,我们有可能还需要获取索引,这时候可以获取数组或者列表的indicates属性,这个属性存储的就是索引,比如说我们如果想要像之前像Java里一样用for循环进行遍历就可以这样写:
val array1 = arrayOf(1,2,3,4,5)
for (x in array1.indices){
println("index:$x,number:${array1.get(x)}")
}
除此之外我们还可以使用解构来遍历:
val array1 = arrayOf(1,2,3,4,5)
for ( (index,number) in array1.withIndex()){
println("index:$index,number:${number}")
}
这里使用了withIndex方法,第一个解构出来的就是索引,第二个就是内容。
Kotlin中的when和Java中的when是不一样的,它可能更接近于Java中的switch关键字。在Kotlin中when可以替换一系列if-else语句或者表达式,其实就相当于升级版的switch:
fun whatTodo(dayOfweek:Any):String{
return when(dayOfweek){
"Saturday","Sunday" -> "Relax"
"Monday","Tuesday","Wednesday","Thursday" -> "Work,Work"
"Friday" -> "Party"
else -> "No"
}
}
when语句中通过判断dayOfweek来决定最终的输出,在->符号左边是相当于Java中switch-case的case后面的值,->右边是冒号后面的操作。不同在于when语句可以当做是一个表达式,在这里就相当于是一个String的表达式。
初次之外,when语句的->左边还可以是一个布尔类型的值,为true时执行右边的操作,执行顺序也是从上到下。比如我们可以看看下面这个例子:
fun classToShow(cl:Any):String{
return when(cl){
is Int -> "Integer"
is String -> "String"
is Boolean -> "Boolean"
is Char -> "Char"
else -> "Not Found"
}
}
这个函数中就会根据cl的类型来决定输出的字符串。
在Kotlin中的迭代和Java中的比较大的区别可能就是Kotlin中新增了范围类,通过操作这些范围类我们就可以灵活地遍历了。除此之外,when语句也是kotlin中更加灵活的语句。合理地使用when语句可以大大简化我们的代码,提升简洁性。