집합 연산자
- 연산자 1 설정(이니셜 a - f)
이 문서 Kotlin
에서는 컬렉션의 연산자를 소개합니다. Kotlin
이 문서에서 사용된 버전은 1.8.10입니다.
all
컬렉션의 모든 요소가 요구 사항을 충족하는지 확인하고 반환 값은Boolean
예를 들어 문자열의 길이가 4보다 큰지 여부를 확인해야 합니다.
val songs = listOf("一路向北", "搁浅", "最长的电影")
songs.all {
it.length >= 4 } // false
源码实现
// 继承Collection并且为空集合,直接返回为true
// 假如有一个元素不满足条件,直接返回false
public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean {
if (this is Collection && isEmpty()) return true
for (element in this) if (!predicate(element)) return false
return true
}
any
컬렉션에 조건을 만족하는 요소가 있는지 확인하고 반환 값은Boolean
예를 들어 185cm 이상의 8팩 복근을 가진 남동생이 있는지 판단해야 합니다.
val heights = listOf(188, 165, 175)
heights.any {
it >= 185 } // true
源码实现
// 继承Collection并且为空集合,直接返回为false
// 假如有一个元素满足条件,直接返回true
public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {
if (this is Collection && isEmpty()) return false
for (element in this) if (predicate(element)) return true
return false
}
contains
세트에 요소가 포함되어 있는지 여부로, 다음과 같이 반환됩니다.Boolean
예를 들어, 학급에 Cai Xukun이라는 아이가 있는지 확인하려면
val nickname = listOf("蔡徐坤", "坤蔡徐", "蔡坤徐", "蔡徐坤")
println(nickname.contains("蔡徐坤")) // true
源码实现
// 继承Collection,则通过Collection.contains()判断是否包含
// 负责通过indexOf判断
public operator fun <@kotlin.internal.OnlyInputTypes T> Iterable<T>.contains(element: T): Boolean {
if (this is Collection)
return contains(element)
return indexOf(element) >= 0
}
count
컬렉션의 길이를 반환합니다.
val nickname = listOf("蔡徐坤", "坤蔡徐", "蔡坤徐", "蔡徐坤")
println(nickname.count()) // 4
源码实现
// 继承Collection,返回size
// 使用for循环计数
public fun <T> Iterable<T>.count(): Int {
if (this is Collection) return size
var count = 0
for (element in this) checkCountOverflow(++count)
return count
}
조건에 따라 조건을 만족하는 컬렉션의 모든 요소의 길이를 반환합니다.
예를 들어 키가 185cm에 달하는 학급의 어린이 수를 세어야 합니다.
val height = listOf(188, 165, 175, 185)
println(height.count {
it >= 185 } ) // 2
源码实现
// 集合并且长度为0,返回0
// 满足predicate,计数累加并返回
public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int {
if (this is Collection && isEmpty()) return 0
var count = 0
for (element in this) if (predicate(element)) checkCountOverflow(++count)
return count
}
distinct
컬렉션에서 동일한 요소를 필터링하고 실제로 HashSet
요소가 반복되지 않도록 하여 새 컬렉션을 반환합니다.
예를 들어 이름이 같은 학생을 필터링합니다.
val nickname = listOf("蔡徐坤", "坤蔡徐", "蔡坤徐", "蔡徐坤")
nickname.distinct() // [蔡徐坤, 坤蔡徐, 蔡坤徐]
源码实现
public fun <T> Iterable<T>.distinct(): List<T> {
return this.toMutableSet().toList()
}
distinctBy
조건에 따라 컬렉션의 요소를 필터링하고 실제로 HashSet
요소가 반복되지 않도록 하여 새 컬렉션을 반환합니다.
예를 들어 이름 길이로 필터링
val nickname = listOf("蔡徐坤", "蔡", "坤蔡徐", "蔡坤徐", "蔡徐")
nickname.distinctBy {
it.length } // [蔡徐坤, 蔡, 蔡徐]
같은 요소를 필터링 하고 싶다면 이렇게 작성하면 됩니다( 직접 distinct
사용하는 것이 좋습니다 )distinct
nickname.distinctBy {
it }
源码实现
// HashSet可以添加元素,就将元素添加到list
public inline fun <T, K> Iterable<T>.distinctBy(selector: (T) -> K): List<T> {
val set = HashSet<K>()
val list = ArrayList<T>()
for (e in this) {
val key = selector(e)
if (set.add(key))
list.add(e)
}
return list
}
drop
n
컬렉션의 첫 번째 요소를 필터링 하고 새 컬렉션을 반환합니다. 예외를 n < 0
던지고 , 원래 컬렉션을 반환하고, 빈 컬렉션을 반환합니다.IllegalArgumentException
n = 0
n >= 集合长度
val heroName = listOf("蛮三刀", "托儿索", "儿童劫", "提款姬", "菊花信")
println(heroName.drop(0)) // [蛮三刀, 托儿索, 儿童劫, 提款姬, 菊花信]
println(heroName.drop(2)) // [儿童劫, 提款姬, 菊花信]
println(heroName.drop(6)) // []
源码实现
// n = 0,返回toList()
// 继承Collection时,获取去除后的集合长度,长度为0返回emptyList,长度为1返回最后一个元素,否则通过ArrayList添加元素
public fun <T> Iterable<T>.drop(n: Int): List<T> {
require(n >= 0) {
"Requested element count $n is less than zero." }
if (n == 0) return toList()
val list: ArrayList<T>
if (this is Collection<*>) {
val resultSize = size - n
if (resultSize <= 0)
return emptyList()
if (resultSize == 1)
return listOf(last())
list = ArrayList<T>(resultSize)
if (this is List<T>) {
if (this is RandomAccess) {
for (index in n until size)
list.add(this[index])
} else {
for (item in listIterator(n))
list.add(item)
}
return list
}
}
else {
list = ArrayList<T>()
}
var count = 0
for (item in this) {
if (count >= n) list.add(item) else ++count
}
return list.optimizeReadOnlyList()
}
dropLast
반대 drop
는 dropLast
꼬리에서 필터링하는 것입니다. 예외를 n < 0
던지고 , 원래 컬렉션을 반환하고, 빈 컬렉션을 반환합니다.IllegalArgumentException
n = 0
n >= 集合长度
val heroName = listOf("蛮三刀", "托儿索", "儿童劫", "提款姬", "菊花信")
println(heroName.dropLast(0)) // [蛮三刀, 托儿索, 儿童劫, 提款姬, 菊花信]
println(heroName.dropLast(2)) // [蛮三刀, 托儿索, 儿童劫]
println(heroName.dropLast(6)) // []
源码实现
// 通过take()获取结果,take后面再说
public fun <T> List<T>.dropLast(n: Int): List<T> {
require(n >= 0) {
"Requested element count $n is less than zero." }
return take((size - n).coerceAtLeast(0))
}
dropLastWhile
조건에 따라 끝에서부터 요소를 필터링하고, 조건에 맞지 않는 요소일 경우 반환
예를 들어 현재 구직자가 너무 많고 회사는 선착순 원칙을 고수해야하며 키가 큰 사람에게 더 적합한 직책을 마지막에 구직자를 폐기해야합니다
val heights = listOf(185, 158, 177, 190, 169, 170, 168)
println(heights.dropLastWhile {
it <= 175 }) // [185, 158, 177, 190]
println(heights.dropLastWhile {
it < 170 }) // [185, 158, 177, 190, 169, 170]
源码实现
// 通过迭代器从后到前迭代,直到不满足条件时通过take截取
public inline fun <T> List<T>.dropLastWhile(predicate: (T) -> Boolean): List<T> {
if (!isEmpty()) {
val iterator = listIterator(size)
while (iterator.hasPrevious()) {
if (!predicate(iterator.previous())) {
return take(iterator.nextIndex() + 1)
}
}
}
return emptyList()
}
dropWhile
조건에 따라 헤드에서 요소를 필터링합니다. 반대로 dropLastWhile
요소가 조건을 충족하지 않을 때까지 나머지 컬렉션을 반환합니다.
여전히 위의 예이지만 선별 규칙을 조정하면 회사는 선착순 및 남성 (또는 여성) 우선의 원칙이 필요하며 상위 구직자를 버립니다.
val names = listOf("陈女士", "张先生", "王先生", "蔡女士", "李先生", "钟女士", "朱先生")
println(names.dropWhile {
it.endsWith("女士") }) // [张先生, 王先生, 蔡女士, 李先生, 钟女士, 朱先生]
println(names.dropWhile {
it.endsWith("先生") }) // [陈女士, 张先生, 王先生, 蔡女士, 李先生, 钟女士, 朱先生]
源码实现
// for循环遍历,如果某个元素不满足条件,就把这个元素添加到集合并且把yielding置为true,后续的元素全部添加到集合
public inline fun <T> Iterable<T>.dropWhile(predicate: (T) -> Boolean): List<T> {
var yielding = false
val list = ArrayList<T>()
for (item in this)
if (yielding)
list.add(item)
else if (!predicate(item)) {
list.add(item)
yielding = true
}
return list
}
elementAt
인덱스 아래의 요소를 반환합니다. 인덱스가 유효한 범위 [0, lastIndex]에 없으면 배열 범위를 벗어난 예외가 발생합니다. 또는 대신 사용할 수 elementAtOrNull
있습니다 elementAtOrElse
.
val mobileGames = listOf("和平精英", "英雄联盟手游", "欢乐斗地主")
println(mobileGames.elementAt(1)) // 英雄联盟手游
println(mobileGames.elementAt(mobileGames.lastIndex + 1)) // java.lang.ArrayIndexOutOfBoundsException 异常
源码实现
// List通过get方法获取
// 否则通过elementAtOrElse
public fun <T> Iterable<T>.elementAt(index: Int): T {
if (this is List)
return get(index)
return elementAtOrElse(index) {
throw IndexOutOfBoundsException("Collection doesn't contain element at index $index.") }
}
elementAtOrElse
인덱스 아래의 요소를 반환하고 인덱스가 유효한 범위 [0, lastIndex]에 있지 않으면 기본값을 반환합니다.
val mobileGames = listOf("和平精英", "英雄联盟手游", "欢乐斗地主")
println(mobileGames.elementAtOrElse(1) {
"未找到游戏" }) // 英雄联盟手游
println(mobileGames.elementAtOrElse(mobileGames.lastIndex + 1) {
"未找到游戏" }) // 未找到游戏
源码实现
public fun <T> Iterable<T>.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T {
if (this is List)
return this.getOrElse(index, defaultValue)
if (index < 0)
return defaultValue(index)
val iterator = iterator()
var count = 0
while (iterator.hasNext()) {
val element = iterator.next()
if (index == count++)
return element
}
return defaultValue(index)
}
elementAtOrNull
인덱스 아래의 요소를 반환하거나 인덱스가 유효한 범위 [0, lastIndex]에 없으면 null을 반환합니다.
예를 들어
val list = listOf(1, 2, 3, 4, 5)
list.elementAtOrNull(3) = 4
list.elementAtOrNull(5) = null
源码实现
public fun <T> Iterable<T>.elementAtOrNull(index: Int): T? {
if (this is List)
return this.getOrNull(index)
if (index < 0)
return null
val iterator = iterator()
var count = 0
while (iterator.hasNext()) {
val element = iterator.next()
if (index == count++)
return element
}
return null
}
filter
조건별로 요소를 필터링하여 조건을 충족하는 모든 요소를 반환합니다.
예를 들어
val names = listOf("司马懿", "诸葛亮", "吕布", "黄忠", "赵云", "凤雏庞统")
println(names.filter {
it.length >= 3 })
源码实现
// 通过filterTo实现,filterTo后面再说
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
filterIndexed
조건별로 요소를 필터링합니다. 차이점은 함수 유형의 매개변수가 유형의 인덱스를 갖는다는 것 filter
입니다.filterIndexed
int
index
예를 들어 컬렉션을 싱글과 더블로 나눕니다.
val names = listOf("司马懿", "诸葛亮", "吕布", "黄忠", "赵云", "凤雏庞统")
val even = names.filterIndexed {
index, _ -> index % 2 == 0 } // [司马懿, 吕布, 赵云]
val odd = names.filterIndexed {
index, _ -> index % 2 == 1 } // [诸葛亮, 黄忠, 凤雏庞统]
源码实现
// 通过filterIndexedTo实现,传进去的集合是ArrayList
public inline fun <T> Iterable<T>.filterIndexed(predicate: (index: Int, T) -> Boolean): List<T> {
return filterIndexedTo(ArrayList<T>(), predicate)
}
filterIndexedTo
조건별로 요소를 필터링하고 필터링된 요소를 컬렉션에 추가합니다.
val names = listOf("司马懿", "诸葛亮", "司马懿", "吕布", "黄忠", "赵云", "凤雏庞统")
val evenSet = hashSetOf<String>()
val oddSet = hashSetOf<String>()
val even = names.filterIndexedTo(evenSet) {
index, _ -> index % 2 == 0 } // [司马懿, 凤雏庞统, 黄忠]
val odd = names.filterIndexedTo(oddSet) {
index, _ -> index % 2 == 1 } // [吕布, 诸葛亮, 赵云]
源码实现
// 传进来的集合必须是MutableCollection,因为会通过这个集合去添加过滤后的元素,返回传进来的集合
// 通过forEachIndexed过滤满足条件的元素
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C {
forEachIndexed {
index, element ->
if (predicate(index, element)) destination.add(element)
}
return destination
}
filterIsInstance
동일한 유형의 요소를 필터링하고 새 컬렉션을 반환합니다.
String
예를 들어, 다음 과 같은 Int
컬렉션 이 있습니다.
val typeValues = listOf("蔡徐坤", 88, "唱跳rap", "篮球", 177, 68)
println(typeValues.filterIsInstance<String>()) // [蔡徐坤, 唱跳rap, 篮球]
println(typeValues.filterIsInstance<Int>()) // [88, 177, 68]
源码实现
// 通过filterIsInstanceTo实现,参数是ArrayList
public inline fun <reified R> Iterable<*>.filterIsInstance(): List<@kotlin.internal.NoInfer R> {
return filterIsInstanceTo(ArrayList<R>())
}
filterIsInstanceTo
동일한 유형의 요소를 필터링하고 필터링된 요소를 컬렉션에 추가
val stringSet = hashSetOf<String>()
val intSets = hashSetOf<Int>()
val typeValues = listOf("蔡徐坤", 88, "唱跳rap", "篮球", 177, 68)
println(typeValues.filterIsInstanceTo(stringSet))
println(typeValues.filterIsInstanceTo(intSets))
源码实现
// 通过for循环遍历集合,将符合类型的元素添加到传进来的集合中
public inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceTo(destination: C): C {
for (element in this) if (element is R) destination.add(element)
return destination
}
filterNot
filter
조건별로 요소를 필터링하고 조건을 충족 하지 않는 모든 요소를 반환합니다.
예를 들어 이름 길이가 4가 아닌 대학을 가져와야 합니다.
val universitySet =
setOf("厦门大学", "四川大学", "清华大学", "中山大学", "武汉理工大学", "华南理工大学", "中国传媒大学")
println(universitySet.filterNot {
it.length == 4 }) // [武汉理工大学, 华南理工大学, 中国传媒大学]
源码实现
// 通过filterNotTo过滤
public inline fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T> {
return filterNotTo(ArrayList<T>(), predicate)
}
filterNotNull
null
의 요소를 필터링
val random = listOf<Any?>("蔡徐坤", 2.5f, "唱跳rap", null)
println(random.filterNotNull()) //[蔡徐坤, 2.5, 唱跳rap]
源码实现
// 通过filterNotNullTo过滤
public fun <T : Any> Iterable<T?>.filterNotNull(): List<T> {
return filterNotNullTo(ArrayList<T>())
}
filterNotNullTo
의 요소를 필터링 null
하고 나머지 요소를 들어오는 컬렉션에 추가합니다.
val random = listOf<Any?>("蔡徐坤", 2.5f, "唱跳rap", null)
val hashSet = hashSetOf<Any>()
println(random.filterNotNullTo(hashSet)) // [2.5, 唱跳rap, 蔡徐坤]
源码实现
// 如果元素为空,则添加到传进来的集合中
public fun <C : MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(destination: C): C {
for (element in this) if (element != null) destination.add(element)
return destination
}
filterNotTo
조건별로 요소를 필터링하고 조건을 충족하지 않는 요소를 수신 컬렉션에 추가합니다.
예를 들어
val universitySet =
setOf("厦门大学", "四川大学", "清华大学", "中山大学", "武汉理工大学", "华南理工大学", "中国传媒大学")
val lenNot4Items = hashSetOf<String>()
println(universitySet.filterNotTo(lenNot4Items) {
it.length == 4 }) // [武汉理工大学, 华南理工大学, 中国传媒大学]
源码实现
// 将不满足条件的元素添加到传进来的集合中
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterNotTo(destination: C, predicate: (T) -> Boolean): C {
for (element in this) if (!predicate(element)) destination.add(element)
return destination
}
filterTo
조건별로 요소를 필터링하고 들어오는 컬렉션에 조건을 만족하는 요소를 추가합니다 filterNotTo
.
예를 들어
@Test
fun filterToExample() {
val universitySet =
setOf("厦门大学", "四川大学", "清华大学", "中山大学", "武汉理工大学", "华南理工大学", "中国传媒大学")
val len4Items = hashSetOf<String>()
println(universitySet.filterTo(len4Items) {
it.length == 4 }) // [厦门大学, 四川大学, 中山大学, 清华大学]
}
源码实现
// for循环遍历,将满足条件的添加到集合
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
for (element in this) if (predicate(element)) destination.add(element)
return destination
}
find
조건에 따라 조건을 만족하는 첫 번째 요소를 찾아 찾으면 바로 리턴, 없으면 null 리턴
예를 들어
val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.find {
it.startsWith("A") }) // Apple
println(company.find {
it.endsWith("G") }) // null
源码实现
// 内部通过firstOrNull实现
public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}
findLast
조건에 따라 조건을 만족하는 마지막 요소를 찾아 찾으면 바로 리턴하고 찾지 못하면 find
검색 순서와 반대인 null을 리턴한다.
예를 들어
val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.findLast {
it.startsWith("A") }) // Alibaba
println(company.findLast {
it.endsWith("G") }) // null
源码实现
// 内部通过lastOrNull实现
public inline fun <T> List<T>.findLast(predicate: (T) -> Boolean): T? {
return lastOrNull(predicate)
}
first
첫 번째 요소 또는 조건을 만족하는 첫 번째 요소를 반환합니다. 요소를 찾을 수 없으면 NoSuchElementException
예외가 발생합니다. firstOrNull
대신 사용할 수 있습니다.
예를 들어
val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.first()) // Google
println(company.first {
it.startsWith("A") }) // Apple
println(company.first {
it.endsWith("G") }) // java.util.NoSuchElementException: Collection contains no element matching the predicate.
源码实现
public fun <T> List<T>.first(): T {
if (isEmpty())
throw NoSuchElementException("List is empty.")
return this[0]
}
// List 返回首个元素
// 否则使用迭代器返回
public fun <T> Iterable<T>.first(): T {
when (this) {
is List -> return this.first()
else -> {
val iterator = iterator()
if (!iterator.hasNext())
throw NoSuchElementException("Collection is empty.")
return iterator.next()
}
}
}
firstNotNullOf
변환된 null이 아닌 첫 번째 요소를 반환하거나 없는 경우 NoSuchElementException
예외를 throw합니다.
예를 들어
val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
val companyMap = hashMapOf("抖音" to "字节", "快手" to "快手集团", "企鹅" to "腾讯")
println(company.firstNotNullOf {
it.length }) // 6
println(company.firstNotNullOf {
companyMap[it] }) // java.util.NoSuchElementException: No element of the collection was transformed to a non-null value.
源码实现
// 将转换函数传递给firstNotNullOfOrNull,如果firstNotNullOfOrNull返回空则抛出异常
public inline fun <T, R : Any> Iterable<T>.firstNotNullOf(transform: (T) -> R?): R {
return firstNotNullOfOrNull(transform) ?: throw NoSuchElementException("No element of the collection was transformed to a non-null value.")
}
firstNotNullOfOrNull
변환된 null이 아닌 첫 번째 요소를 반환하거나 없음을 반환합니다.null
예를 들어
val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
val companyMap = hashMapOf("抖音" to "字节", "快手" to "快手集团", "企鹅" to "腾讯")
println(company.firstNotNullOfOrNull {
it.length }) // 6
println(company.firstNotNullOfOrNull {
companyMap[it] }) // null
源码实现
// 获取转换之后的值,如果不是空就返回
public inline fun <T, R : Any> Iterable<T>.firstNotNullOfOrNull(transform: (T) -> R?): R? {
for (element in this) {
val result = transform(element)
if (result != null) {
return result
}
}
return null
}
firstOrNull
반환하지 않으면 첫 번째 요소 또는 조건을 만족하는 첫 번째 요소를 반환합니다.null
예를 들어
val company = listOf("Google", "Microsoft", "IBM", "Apple", "Yahoo", "Alibaba", "Baidu")
println(company.firstOrNull()) // Google
println(company.firstOrNull {
it.startsWith("A") }) // Apple
println(company.firstOrNull {
it.endsWith("G") }) // null
源码实现
// 对list单独处理,其他都是通过迭代器处理
public fun <T> Iterable<T>.firstOrNull(): T? {
when (this) {
is List -> {
if (isEmpty())
return null
else
return this[0]
}
else -> {
val iterator = iterator()
if (!iterator.hasNext())
return null
return iterator.next()
}
}
}
// for循环遍历
public inline fun <T> Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T? {
for (element in this) if (predicate(element)) return element
return null
}
flatMap
세트의 요소는 변환 함수에 따라 새로운 값을 얻고 모든 값은 새 세트로 병합됩니다. map
와 달리 flatMap
변환 함수는 새로운 컬렉션을 반환해야 하며 변환된 값을 컬렉션으로 병합하므로 단일 레이어 컬렉션으로 변환된 중첩된 컬렉션이 있는 경우 사용하십시오.flatMap
예를 들어
val intList = listOf(1, 2, 3, 4, 5)
val nestList = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6, 7))
println(intList.flatMap {
listOf(it + it, it * it, it * it * it) }) // [2, 1, 1, 4, 4, 8, 6, 9, 27, 8, 16, 64, 10, 25, 125]
println(nestList.flatMap {
item -> item.map {
it * it } }) // [1, 4, 9, 16, 25, 36, 49]
源码实现
// flatMapTo到ArrayList
public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {
return flatMapTo(ArrayList<R>(), transform)
}
flatMapIndexed
와 동일 flatMap
하지만 lambda
추가 index
색인 매개변수가 있음
예를 들어
val intList = listOf(1, 2, 3, 4, 5)
println(intList.flatMapIndexed {
index, it -> listOf(it + it, it * it, it * it * it) })
源码实现
// flatMapIndexedTo到ArrayList
public inline fun <T, R> Iterable<T>.flatMapIndexed(transform: (index: Int, T) -> Iterable<R>): List<R> {
return flatMapIndexedTo(ArrayList<R>(), transform)
}
flatMapIndexedTo
flatMapIndexed
들어오는 컬렉션에 변환된 요소를 추가하는 최종 구현의 소스 코드
예를 들어
val intList = listOf(1, 2, 3, 4, 5)
val hashSet = hashSetOf<Int>()
println(intList.flatMapIndexedTo(hashSet) {
index, it -> listOf(it + it, it * it, it * it * it) }) // [16, 64, 1, 2, 4, 6, 8, 9, 25, 10, 27, 125]
println(hashSet) // [16, 64, 1, 2, 4, 6, 8, 9, 25, 10, 27, 125]
源码实现
// 遍历整个集合,将转换函数获得的集合添加到传进来的集合中
// checkIndexOverflow是防止数组越界
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapIndexedTo(destination: C, transform: (index: Int, T) -> Iterable<R>): C {
var index = 0
for (element in this) {
val list = transform(checkIndexOverflow(index++), element)
destination.addAll(list)
}
return destination
}
flatMapTo
flatMap
들어오는 컬렉션에 변환된 요소를 추가하는 최종 구현의 소스 코드
val nestList = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6, 7))
val destSet = hashSetOf<Int>()
println(nestList.flatMapTo(destSet) {
item -> item.map {
it * it } })
println(destSet)
源码实现
// 遍历整个集合,将转换函数获得的集合添加到传进来的集合中
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapTo(destination: C, transform: (T) -> Iterable<R>): C {
for (element in this) {
val list = transform(element)
destination.addAll(list)
}
return destination
}
fold
각 요소에 대해 연산하여 누적된 총 값을 반환합니다. 세트가 비어 있으면 초기 값을 반환합니다.
예를 들어, 1에서 5까지의 합 또는 제곱합을 계산해야 합니다.
val intList = listOf(1, 2, 3, 4, 5)
println(intList.fold(0) {
prev, item -> prev + item }) // 15
println(intList.fold(0) {
prev, item -> prev + item * item }) // 55
源码实现
// 遍历整个集合,将上一个的结果传到下一个的遍历中,需要传入初始值
public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {
var accumulator = initial
for (element in this) accumulator = operation(accumulator, element)
return accumulator
}
foldIndexed
fold
와 같지만 추가 lambda
색인 index
매개변수 가 있는
val intList = listOf(1, 2, 3, 4, 5)
println(intList.foldIndexed(0) {
index, prev, item -> prev + item })
println(intList.foldIndexed(0) {
index, prev, item -> prev + item * item })
源码实现
// 遍历整个集合,将上一个的结果传到下一个的遍历中,需要传入初始值
public inline fun <T, R> Iterable<T>.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R {
var index = 0
var accumulator = initial
for (element in this) accumulator = operation(checkIndexOverflow(index++), accumulator, element)
return accumulator
}
foldRight
각 요소에 대해 연산하여 누적된 총 값을 반환합니다. 와의 차이점은 오른쪽에서 왼쪽으로, 왼쪽에서 오른쪽으로 누적된다는 것 fold
입니다 . 순차적이기 때문에foldRight
fold
list
val intList = listOf(1, 2, 3, 4, 5)
println(intList.foldRight(0) {
prev, item -> prev + item }) // 15
源码实现
// 通过listIterator迭代整个list,如果为空返回默认值
public inline fun <T, R> *List*<T>.foldRight(initial: R, operation: (T, acc: R) -> R): R {
var accumulator = initial
if (!isEmpty()) {
val iterator = listIterator(size)
while (iterator.hasPrevious()) {
accumulator = operation(iterator.previous(), accumulator)
}
}
return accumulator
}
foldRightIndexed
foldRight
와 같지만 추가 lambda
색인 index
매개변수 가 있는
val intList = listOf(1, 2, 3, 4, 5)
println(intList.foldIndexed(0) {
index, prev, item -> prev + item })
源码实现
// // 通过listIterator迭代整个list,如果为空返回默认值
public inline fun <T, R> *List*<T>.foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R): R {
var accumulator = initial
if (!isEmpty()) {
val iterator = listIterator(size)
while (iterator.hasPrevious()) {
val index = iterator.previousIndex()
accumulator = operation(index, iterator.previous(), accumulator)
}
}
return accumulator
}
forEach
forEach
트래버스, lambda
각 요소 반환
val intList = listOf(1, 2, 3, 4, 5)
intList.forEach {
println(it)
}
// 1 2 3 4 5
源码实现
// for循环遍历
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
forEachIndexed
forEach
와 같지만 추가 lambda
색인 index
매개변수 가 있는
源码实现
// for循环遍历
public inline fun <T> Iterable<T>.forEachIndexed(action: (index: Int, T) -> Unit): Unit {
var index = 0
for (item in this) action(checkIndexOverflow(index++), item)
}
마침내
건축가가 되고 싶거나 연봉 2~3만 대를 돌파하고 싶다면 코딩과 비즈니스에 국한하지 말고 모델을 선택하고 확장하고 프로그래밍 사고를 향상시킬 수 있어야 합니다. 또한 좋은 진로계획도 매우 중요하고, 배움의 습관도 매우 중요하지만 가장 중요한 것은 인내할 수 있는 것입니다.
방향이 없는 경우 여기에서 Ali의 수석 설계자가 작성한 "안드로이드의 8대 주요 모듈에 대한 고급 노트" 세트를 공유하여 복잡하고 흩어져 있고 조각난 지식을 체계적으로 정리할 수 있도록 도와드립니다. 안드로이드 개발의 다양한 지식 포인트를 체계적이고 효율적으로 마스터할 수 있습니다.
우리가 일반적으로 읽는 조각난 콘텐츠와 비교할 때 이 노트의 지식 포인트는 더 체계적이고 이해하고 기억하기 쉽고 지식 시스템에 따라 엄격하게 배열됩니다.
한 번의 클릭과 세 개의 링크로 지원하는 모든 사람을 환영합니다.기사의 정보가 필요한 경우 기사 끝에 있는 CSDN 공식 인증 WeChat 카드를 직접 스캔하여 무료로 얻을 수 있습니다↓↓↓
추신: 그룹에 ChatGPT 로봇도 있어 작업이나 기술적인 질문에 답할 수 있습니다.