Để duyệt qua các phần tử của collection, thư viện chuẩn của Kotlin hỗ trợ cơ chế thường được sử dụng của các trình vòng lặp – các đối tượng cung cấp quyền truy cập vào các phần tử một cách tuần tự mà không để lộ cấu trúc cơ bản của collection. Các trình lặp rất hữu ích khi bạn cần xử lý từng phần tử một của một collection, ví dụ việc in các giá trị hoặc thực hiện các cập nhật tương tự cho chúng.

Trình lặp lại có thể được lấy cho các trình kế thừa của interface Iterable<T>, bao gồm Set và List, bằng cách gọi hàm iterator(). Khi bạn có được một trình lặp, nó trỏ đến phần tử đầu tiên của một collection; việc gọi hàm next() sẽ trả về phần tử này và di chuyển vị trí của trình vòng lặp đến phần tử tiếp theo (nếu có). Khi trình lặp đi qua phần tử cuối cùng, nó không còn có thể được sử dụng để truy xuất các phần tử; nó cũng không thể được đặt lại về bất kỳ vị trí trước đó. Để lặp qua collection một lần nữa, hãy tạo một trình lặp mới.

val numbers = listOf("one", "two", "three", "four")
val numbersIterator = numbers.iterator()
while (numbersIterator.hasNext()) {
    println(numbersIterator.next())
}

Một cách khác để duyệt qua một Iterable collection là sử dụng vòng lặp for vốn được nhiều người biết đến. Khi sử dụng vòng lặp for trên một collection, bạn hoàn toàn có được trình vòng lặp. Vì vậy, đoạn code sau tương đương với code ở ví dụ trên:

val numbers = listOf("one", "two", "three", "four")
for (item in numbers) {
    println(item)
}

Cuối cùng, có một hàm forEach() vô cùng hữu ích cho phép bạn tự động lặp lại một collection và thực hiện code đã cho cho đối với từng phần tử. Vì vậy, sẽ có một ví dụ tương tự như sau:

val numbers = listOf("one", "two", "three", "four")
numbers.forEach {
    println(it)
}

1. Trình vòng lặp cho list (List iterators)

Đối với list, có một triển khai trình vòng lặp đặc biệt đó chính là ListIterator. Nó hỗ trợ lặp lại list theo cả hai hướng tiến và lùi. Việc lặp lại được thực hiện bởi các hàm hasPrevious()previous(). Ngoài ra, ListIterator cung cấp thông tin về các chỉ số của phần tử với các hàm nextIndex()previousIndex().

val numbers = listOf("one", "two", "three", "four")
val listIterator = numbers.listIterator()
while (listIterator.hasNext()) listIterator.next()
println("Iterating backwards:")
while (listIterator.hasPrevious()) {
    print("Index: ${listIterator.previousIndex()}")
    println(", value: ${listIterator.previous()}")
}

Việc có khả năng lặp lại theo cả hai hướng, có nghĩa là ListIterator vẫn có thể được sử dụng sau khi nó đã duyệt đến phần tử cuối cùng.

2. Trình vòng lặp có thể thay đổi (Mutable iterators)

Đối với việc lặp lại các collection có thể thay đổi, MutableIterator sẽ mở rộng Iterator với hàm loại bỏ phần tử là hàm remove(). Vì vậy, bạn có thể xóa các phần tử khỏi collection trong khi lặp lại nó.

val numbers = mutableListOf("one", "two", "three", "four") 
val mutableIterator = numbers.iterator()

mutableIterator.next()
mutableIterator.remove()    
println("After removal: $numbers")

Ngoài việc loại bỏ các phần tử, MutableListIterator cũng có thể chèn và thay thế các phần tử trong khi lặp lại list.

val numbers = mutableListOf("one", "four", "four") 
val mutableListIterator = numbers.listIterator()

mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")   
println(numbers)

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!