Kotlin基础入门 - for、forEach 循环
不论身处何方 for循环这种操作都随处可见,鉴于大多数Android开发都是从Java转到Kt的,所以我的思路是从Java的使用习惯来讲一些Kt 的for、forEach 循环方式
-
-
- 基础 for循环
- 惯性 for循环
- 进阶 for循环
- 倒序 for循环
- forEach循环
- for循环 step过滤
- for循环 同时获取index、数据
- for循环 多变量、多列表
- 总结
-
基础 for循环
for循环
一般作用于list、map数据集合
,这里我直接创建了一个只读List集合
val dataList = listOf("apple", "banana", "orange")
val numList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
提前了解
//Java中获取list循环数据的方式
dataList.get(i)
//Java中获取数组数据的方式
dataList[i]
//在Kt中不论是集合还是数组都用以下方式
dataList[i]
惯性 for循环
所谓的惯性思维,指的是从Java过渡的常规for循环思想,均是循环获取角标,然后根据角标取对应值;如下
for (int i = 0; i < list.size(); i++) { }
惯性方式1
:在 Kt
中,通常使用 start .. end 来代表一段区间
,如下就是类似Java的写法,定义一个变量,循环区间定义在 0 - List.size - 1,循环时获取list中每个索引的值
fun basicsFor1(dataList: List<String>) {
for (i in 0..dataList.size - 1) {
println("basicsFor1:" + dataList[i])
}
}
惯性方式2
:使用Ranges.kt
下的until
来代表循环区间,从而完成 for循环
fun basicsFor2(dataList: List<String>) {
for (i in 0 until dataList.size) {
println("basicsFor2:" + dataList[i])
}
}
输出结果
com.example.fordemo I basicsFor1:apple
com.example.fordemo I basicsFor1:banana
com.example.fordemo I basicsFor1:orange
com.example.fordemo I basicsFor2:apple
com.example.fordemo I basicsFor2:banana
com.example.fordemo I basicsFor2:orange
有的人可能发现 dataList.size 没有-1,这样会不会造成数组越界
?我们看一下 Int 的 until 扩展函数
,你会发现在其内部也是封装了区间处理,故使用无忧
进阶 for循环
Look:以下俩种方式都很常用,可根据需求自行选取
进阶方式1
:使用Collections .kt
下的indices
来代表循环区间,从而完成 for循环
fun basicsFor3(dataList: List<String>) {
for (i in dataList.indices) {
println("basicsFor3:" + i)
println("basicsFor3:" + dataList[i])
}
}
同上疑问,我们看一下 Collection 的 indices扩展属性
,你会发现在其内部也是封装了循环区间
,故亦无忧
输出结果
com.example.fordemo I basicsFor3:0
com.example.fordemo I basicsFor3:apple
com.example.fordemo I basicsFor3:1
com.example.fordemo I basicsFor3:banana
com.example.fordemo I basicsFor3:2
com.example.fordemo I basicsFor3:orange
进阶方式2
:这种方式应该是最快捷的一种循环方式
,从循环区间的定义到值的输出都很方便,但是如果需要角标做一些其他操作的话,并不太适合,可用上者
~
fun basicsFor4(dataList: List<String>) {
for (i in dataList) {
println("basicsFor4:$i")
}
}
输出结果
com.example.fordemo I basicsFor4:apple
com.example.fordemo I basicsFor4:banana
com.example.fordemo I basicsFor4:orange
倒序 for循环
之前的 for循环
方式都是正序的,在一些场景下我们需要倒序,故此也可以学一学
/**
* 倒序
* */
fun invertedFor(numList: List<Int>) {
for (i in numList.size - 1 downTo 0) {
println("invertedFor:" + numList[i])
}
}
没事儿看看 downTo
的源码,发现也是一个区间定义
输出结果
com.example.fordemo I invertedFor:10
com.example.fordemo I invertedFor:9
com.example.fordemo I invertedFor:8
com.example.fordemo I invertedFor:7
com.example.fordemo I invertedFor:6
com.example.fordemo I invertedFor:5
com.example.fordemo I invertedFor:4
com.example.fordemo I invertedFor:3
com.example.fordemo I invertedFor:2
com.example.fordemo I invertedFor:1
forEach循环
众所周知在Java中提供了forEach
循环,同理Kt也支持使用forEach
循环;使用时都是通过 list.forEach...
方式,来看一看提供的方法有forEach
、forEachIndexed
,主要区别在于是否需要index角标
,其余都是重载方法~
forEach
fun forEach(dataList: List<String>) {
dataList.forEach {
println(it)
}
}
输出结果
com.example.fordemo I apple
com.example.fordemo I banana
com.example.fordemo I orange
也可以直接用 区间+forEach循环,以下为示例...
整数型的集合,可以免创建list
fun forEach() {
(0..6).forEach{
println(it)
}
}
输出结果
com.example.fordemo I 0
com.example.fordemo I 1
com.example.fordemo I 2
com.example.fordemo I 3
com.example.fordemo I 4
com.example.fordemo I 5
com.example.fordemo I 6
其他类型需要声明对应的集合,可直接声明全局list或传参函数内部
区间 (0..dataList.size - 1) + forEach
fun forEach(dataList: List<String>) {
(0..dataList.size - 1).forEach {
println(dataList[it])
}
}
输出结果
com.example.fordemo I apple
com.example.fordemo I banana
com.example.fordemo I orange
区间(dataList.indices)+ forEach
fun forEach() {
(dataList.indices).forEach {
println(dataList[it])
}
}
输出结果
com.example.fordemo I apple
com.example.fordemo I banana
com.example.fordemo I orange
forEachIndexed
fun forEachIndexed(dataList: List<String>) {
dataList.forEachIndexed { index, it ->
println("角标=$index 元素=${it}")
}
}
输出结果
com.example.fordemo I 角标=0 元素=apple
com.example.fordemo I 角标=1 元素=banana
com.example.fordemo I 角标=2 元素=orange
for循环 step过滤
step 本意是跳过的意思
,之所以我说是过滤,只因个人感觉step也是过滤数据的一种方式而已
初浅看一下setp函数
,发现支持的入参均为整数型
,故下方案例我们都传整数
常规开发中 step 跳过的数据,一般是 setp数值*倍数(依次从1,2,3...) os:尝试抛开角标的概念,单纯从第几个数的角度去看待这个场景
string集合
for (i in dataList.indices step 2) {
println("stepFor:" + dataList[i])
}
输出结果
com.example.fordemo I stepFor:apple
com.example.fordemo I stepFor:orange
int集合
for (i in numList.indices step 2) {
println("stepFor:" + numList[i])
}
输出结果
com.example.fordemo I stepFor:1
com.example.fordemo I stepFor:3
com.example.fordemo I stepFor:5
com.example.fordemo I stepFor:7
com.example.fordemo I stepFor:9
int集合(倒序)
for (i in numList.size-1 downTo 0 step 2){
println("stepFor:" + numList[i])
}
输出结果
com.example.fordemo I stepFor:10
com.example.fordemo I stepFor:8
com.example.fordemo I stepFor:6
com.example.fordemo I stepFor:4
com.example.fordemo I stepFor:2
for循环 同时获取index、数据
按照以前的常规方式,上方也有讲过
fun basicsIndexItemFor(dataList: List<String>) {
for (index in dataList.indices) {
println("basicsIndexItemFor-index:" + index + " basicsIndexItemFor-item:" + dataList[index])
}
}
输出结果
com.example.fordemo I indexItemFor-index:0 indexItemFor-item:apple
com.example.fordemo I indexItemFor-index:1 indexItemFor-item:banana
com.example.fordemo I indexItemFor-index:2 indexItemFor-item:orange
kt提供的方式(java可能也有)
/**
* 同时获取对应角标(索引)和值,类似map吧
* */
fun indexItemFor(dataList: List<String>) {
for ((index, item) in dataList.withIndex()) {
println("indexItemFor-index:" + index + " indexItemFor-item:" + item)
}
}
输出结果
com.example.fordemo I basicsIndexItemFor-index:0 basicsIndexItemFor-item:apple
com.example.fordemo I basicsIndexItemFor-index:1 basicsIndexItemFor-item:banana
com.example.fordemo I basicsIndexItemFor-index:2 basicsIndexItemFor-item:orange
for循环 多变量、多列表
kt 中的多列表循环,主要用到了 zip
关键字关联集合;这种方式是存在一定不足的,例如当前A列表内部只存在3条数据,B列表数据>3条,最后的结果就是B列表也仅会输出前三条!!!
/**
* 多变量、多列表循环
* */
fun doubleFor(dataList: List<String>,numList: List<Int>) {
for ((i, j) in dataList.indices.zip(numList.indices)) {
println("dataList:" + dataList[i] + " numList:" + numList[j])
}
}
输出结果
com.example.fordemo I dataList:apple numList:1
com.example.fordemo I dataList:banana numList:2
com.example.fordemo I dataList:orange numList:3
kt 提供的这种场景,其实大致等同于以下的循环方式(抛开上面提到的不足)
fun doubleDataFor(dataList: List<String>) {
for (i in dataList.indices) {
println("dataList:" + dataList[i])
}
}
fun doubleNumFor(numList: List<Int>) {
for (i in numList.indices) {
println("numList:" + numList[i])
}
}
输出结果
com.example.fordemo I dataList:apple
com.example.fordemo I dataList:banana
com.example.fordemo I dataList:orange
com.example.fordemo I numList:1
com.example.fordemo I numList:2
com.example.fordemo I numList:3
com.example.fordemo I numList:4
com.example.fordemo I numList:5
com.example.fordemo I numList:6
com.example.fordemo I numList:7
com.example.fordemo I numList:8
com.example.fordemo I numList:9
com.example.fordemo I numList:10
不知道有人会不会有人和我一样懒,既然多列表循环,用的角标值也一样,能不能直接声明一个变量就好...
事实就是提示用Pair
类~ 那么什么是Pair
类呢?
没事儿做,一起看看zip源码
- zip 函数,返回的是
List <Pair<T, R>
-
- Pair类-
- zip 实现-
Pair
类+zip
多列表循环
fun doublePairFor(dataList: List<String>, numList: List<Int>) {
for (Pair in dataList.indices.zip(numList.indices)) {
println("dataList&numList:$Pair")
println("dataList&numList:"+dataList[Pair.first]+"-"+numList[Pair.second])
}
}
输出结果
com.example.fordemo I dataList&numList:(0, 0)
com.example.fordemo I dataList&numList:apple-1
com.example.fordemo I dataList&numList:(1, 1)
com.example.fordemo I dataList&numList:banana-2
com.example.fordemo I dataList&numList:(2, 2)
com.example.fordemo I dataList&numList:orange-3
总结
首先,我写的这些 for循环
都是木有问题的,都循环的很漂亮,知悉一下哈~
-
Demo 源码
package com.example.fordemo
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private val dataList = listOf("apple", "banana", "orange")
private val numList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
basicsFor1(dataList)
basicsFor2(dataList)
basicsFor3(dataList)
basicsFor4(dataList)
invertedFor(numList)
stepFor()
indexItemFor(dataList)
basicsIndexItemFor(dataList)
doubleFor(dataList, numList)
doubleDataFor(dataList)
doubleNumFor(numList)
doublePairFor(dataList, numList)
forEach(dataList)
forEachIndexed(dataList)
}
/**
* step
* */
private fun stepFor() {
for (i in dataList.indices step 2) {
println("stepFor:" + dataList[i])
}
for (i in numList.indices step 2) {
println("stepFor:" + numList[i])
}
for (i in numList.size - 1 downTo 0 step 2) {
println("stepFor:" + numList[i])
}
}
private fun forEach(dataList: List<String>) {
dataList.forEach {
println(it)
}
}
private fun forEachIndexed(dataList: List<String>) {
dataList.forEachIndexed { index, it ->
println("角标=$index 元素=${it}")
}
}
private fun basicsFor1(dataList: List<String>) {
for (i in 0..dataList.size - 1) {
println("basicsFor1:" + dataList[i])
}
}
private fun basicsFor2(dataList: List<String>) {
for (i in 0 until dataList.size) {
println("basicsFor2:" + dataList[i])
}
}
private fun basicsFor3(dataList: List<String>) {
for (i in dataList.indices) {
println("basicsFor3:" + i)
println("basicsFor3:" + dataList[i])
}
}
private fun basicsFor4(dataList: List<String>) {
for (i in dataList) {
println("basicsFor4:$i")
}
}
/**
* 倒序
* */
private fun invertedFor(numList: List<Int>) {
for (i in numList.size - 1 downTo 0) {
println("invertedFor:" + numList[i])
}
}
/**
* 同时获取对应角标(索引)和值,类似map吧
* */
private fun indexItemFor(dataList: List<String>) {
for ((index, item) in dataList.withIndex()) {
println("indexItemFor-index:" + index + " indexItemFor-item:" + item)
}
}
private fun basicsIndexItemFor(dataList: List<String>) {
for (index in dataList.indices) {
println("basicsIndexItemFor-index:" + index + " basicsIndexItemFor-item:" + dataList[index])
}
}
/**
* 多变量、多列表循环
* */
private fun doubleFor(dataList: List<String>, numList: List<Int>) {
for ((i, j) in dataList.indices.zip(numList.indices)) {
println("dataList:" + dataList[i] + " numList:" + numList[j])
}
}
private fun doubleDataFor(dataList: List<String>) {
for (i in dataList.indices) {
println("dataList:" + dataList[i])
}
}
private fun doubleNumFor(numList: List<Int>) {
for (i in numList.indices) {
println("numList:" + numList[i])
}
}
private fun doublePairFor(dataList: List<String>, numList: List<Int>) {
for (Pair in dataList.indices.zip(numList.indices)) {
println("dataList&numList:$Pair")
println("dataList&numList:" + dataList[Pair.first] + "-" + numList[Pair.second])
}
}
/* fun forMonth4(dataList: List<String>) {
repeat(3){
for (data in dataList.indices){
println(data)
}
}
}
fun forMonth4(dataList: List<String>) {
repeat(3){
for (data in dataList.indices){
println(data)
}
}
}*/
}
具体使用哪种循环方式,根据自身需求寻找即可,但是使用基础for循环
时 AndroidStudio
会报警告,具体如下
根据提示 - 修改警告内容后,你会发现 for循环方式 都变为了 进阶for循环 中的常用方式了~
同时获取index、数据
step过滤
多变量、多列表循环 > <