Kotlin中 for in 是有序的吗?forEach呢?

我们要遍历一个数组、一个列表,经常会用到kotlin的 for in 语法,但是 for in 是不是有序的呢?forEach是不是有序的呢?这就需要看一下它们的本质了。

数组的 for in

kotlin 复制代码
// 调用:
val arr = arrayOf(1, 2, 3)
for (ele in arr) {
    println(ele)
}

反编译成Java是个什么东西呢?

java 复制代码
Integer[] arr = new Integer[]{1, 2, 3};
Integer[] var4 = arr;
int var5 = arr.length;

for(int var3 = 0; var3 < var5; ++var3) {
    int ele = var4[var3];
    System.out.println(ele);
}

总结:从Java代码可以看出,实际就是一个普通的for循环,是从下标0开始遍历到结束的,所以是有序的。

列表的 for in

kotlin 复制代码
// 调用:
val list = listOf(1, 2, 3)
for (ele in list) {
    println(ele)
}

反编译成Java:

java 复制代码
List list = CollectionsKt.listOf(new Integer[]{1, 2, 3});
Iterator var3 = list.iterator();

while(var3.hasNext()) {
    int ele = ((Number)var3.next()).intValue();
    System.out.println(ele);
}

可以看出列表的for in是通过iterator实现的,和数组不一样,那这个iterator遍历是否是有序的呢?首先我们要知道这个iterator怎么来的:

kotlin 复制代码
// iterator 是通过调用 list.iterator() 得到的,那么这个list又是什么呢?
Iterator var3 = list.iterator();

// list
List list = CollectionsKt.listOf(new Integer[]{1, 2, 3});

// list是通过数组elements.asList()得到的
public fun <T> listOf(vararg elements: T): List<T> = if (elements.size > 0) elements.asList() else emptyList()

// 这里有个expect,找到对应的actual
public expect fun <T> Array<out T>.asList(): List<T>

// 对应的actual
public actual fun <T> Array<out T>.asList(): List<T> {
    return ArraysUtilJVM.asList(this)
}

// 最终调用了Arrays.asList(array)
class ArraysUtilJVM {
    static <T> List<T> asList(T[] array) {
        return Arrays.asList(array);
    }
}

public class Arrays {
    
    // 从这里看到最终拿到的list是 Arrays 类中的 ArrayList
    // 然后我们找到里面的 iterator() 方法
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private final E[] a;

        @Override
        public Iterator<E> iterator() {
            // 最终得到的iterator是ArrayItr
            // 这里的a是一个数组,也就是我们一开始传进来的1,2,3
            return new ArrayItr<>(a);
        }
    }

    private static class ArrayItr<E> implements Iterator<E> {
        private int cursor;
        private final E[] a;

        ArrayItr(E[] a) {
            this.a = a;
        }

        @Override
        public boolean hasNext() {
            return cursor < a.length;
        }

        @Override
        public E next() {
            int i = cursor;
            if (i >= a.length) {
                throw new NoSuchElementException();
            }
            cursor = i + 1;
            return a[i];
        }
    }
}

总结:列表的for in是通过iterator实现的,这个iterator是ArrayItr,从里面的next()方法可以看出,这也是有序的,从cursor开始,cursor默认是0,也就是从下标0开始遍历。 注:这里只是分析了Arrays.ArrayList的iterator,具体的集合类需要具体分析,比如ArrayList、LinkedList等,不过从正常思维来看,iterator是一个迭代器,就应该有序的把数据一个一个丢出来。

数组的 forEach

kotlin 复制代码
// 调用:
val arr = arrayOf(1, 2, 3)
arr.forEach {
    println(it)
}

// 点进去forEach看:
// 其实也是调用了for in,所以也是有序的。
public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

列表的 forEach

kotlin 复制代码
// 调用:
val list = listOf(1, 2, 3)
list.forEach {
    println(it)
}

// 点进去forEach看:
// 其实也是调用了for in,所以也是有序的。
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}
相关推荐
Kapaseker4 小时前
如果你还没有搞懂 Kotlin 委托属性,进来看看
android·kotlin
唔661 天前
原生 Android(Kotlin)仅串口「继承架构」完整案例二
android·开发语言·kotlin
错把套路当深情1 天前
Kotlin 全方向开发技术栈指南
开发语言·kotlin
stevenzqzq1 天前
Kotlin 协程:withContext 与 async 核心区别与使用场景
android·开发语言·kotlin
stevenzqzq1 天前
Kotlin 语法深度拆解:从 Java 匿名内部类到极简 Lambda 完整演进
java·kotlin·lambda
唔661 天前
原生 Android(Kotlin)仅串口「侵入式架构」完整案例三
android·架构·kotlin
唔661 天前
原生 Android(Kotlin)仅串口「可插拔架构」完整案例一
android·架构·kotlin
Kapaseker1 天前
Compose 响应式布局要变天—入门 FlexBox
android·kotlin
alexhilton2 天前
在Compose中用Shader实现透明的粘稠元球效果
android·kotlin·android jetpack
jinanwuhuaguo2 天前
OpenClaw 2026.4.5 深度解读
android·开发语言·人工智能·kotlin·openclaw