如果您正在阅读此博客,那么我们很确定您已经完全转向 Kotlin 进行 Android 开发,或者您计划很快转向 Kotlin。在任何情况下,此博客都非常适合您。所以,让我们进入正题。

在我们的 Android 应用程序中,我们处理各种集合,例如列表、地图、集合等。我们对这些执行了许多操作,但是您是否知道有许多 Kotlin 集合函数可以让我们的生活更轻松。如果您想对任何集合执行一些操作(简单或复杂),那么很有可能必须有一些集合功能可以使您的整个 Android App 开发变得更简单和容易。

在本博客中,我们将了解其中的许多 Kotlin 集合函数。您可以将此博客添加为书签,并将此博客作为 Kotlin 集合函数的备忘单。所以,让我们从一个简单的操作开始,即从数组中删除重复的字符串。

删除重复的字符串

有很多方法可以从数组中删除重复的字符串:

// Maintain the original order of items
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.distinct()) // [Amit, Ali, Sumit, Himanshu]
// Maintain the original order of items
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.toSet()) // [Amit, Ali, Sumit, Himanshu]
// Maintain the original order of items
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.toMutableSet()) // [Amit, Ali, Sumit, Himanshu]
// DO NOT Maintain the original order of items
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.toHashSet()) // [Amit, Ali, Sumit, Himanshu]

将数组或列表转换为字符串

您可以使用 将数组或列表转换为字符串joinToString。例如,如果您有一个城市列表(德里、孟买、班加罗尔),那么您可以将该列表转换为一个字符串,例如“印度是最佳旅游国家之一。您可以访问德里、孟买、班加罗尔等,享受你的假期”。在这里,德里、孟买、班加罗尔是您拥有的清单项目。

val someKotlinCollectionFunctions = listOf(
    "distinct", "map",
    "isEmpty", "contains",
    "filter", "first",
    "last", "reduce",
    "single", "joinToString"
val message = someKotlinCollectionFunctions.joinToString(
    separator = ", ",
    prefix = "Kotlin has many collection functions like: ",
    postfix = "and they are awesome.",
    limit = 3,
    truncated = "etc "
print(message) // Kotlin has many collection functions like: distinct, map, isEmpty, etc and they are awesome.

将集合转换为单个结果

如果要将给定的集合转换为单个结果,则可以使用reducefunction. 例如,您可以找到列表中所有元素的总和:

val numList = listOf(1, 2, 3, 4, 5)
val result = numList.reduce { result, item ->
    result + item
print(result) // 15
// NOTE: If the list is empty, then it will throw a RuntimeException

查找是否所有元素都满足特定条件

如果您有一个数据元素的数组或列表,并且想要查找是否所有元素都满足特定条件,那么您可以all在 Kotlin 中使用。

data class User(val id: Int, val name: String, val isCricketLover: Boolean, val isFootballLover: Boolean)
val user1 = User(id = 1, name = "Amit", isCricketLover = true, isFootballLover = true)
val user2 = User(id = 2, name = "Ali", isCricketLover = true, isFootballLover = true)
val user3 = User(id = 3, name = "Sumit", isCricketLover = true, isFootballLover = false)
val user4 = User(id = 4, name = "Himanshu", isCricketLover = true, isFootballLover = false)
val users = arrayOf(user1, user2, user3, user4)
val allLoveCricket = users.all { it.isCricketLover }
print(allLoveCricket) // true
val allLoveFootball = users.all { it.isFootballLover }
print(allLoveFootball) // false

根据特定条件查找特定元素

您可以通过在 Kotlin 中使用findand从满足特定条件的元素列表中找到特定元素。single例如,在学生列表中,您可以找到卷号为 5 的学生。

find返回匹配给定条件的第一个元素,如果没有找到这样的元素,则返回 null 。

Whilesingle返回匹配给定条件的单个元素,或者如果列表中有多个匹配元素或没有匹配元素,则会抛出异常。

data class User(val id: Int, val name: String)
val users = arrayOf(
    User(1, "Amit"),
    User(2, "Ali"),
    User(3, "Sumit"),
    User(4, "Himanshu")
val userWithId3 = users.single { it.id == 3 }
print(userWithId3) // User(id=3, name=Sumit)
val userWithId1 = users.find { it.id == 1 }
print(userWithId1) // User(id=1, name=Amit)

将您的列表分成多个较小的子列表

在很多情况下,您有一个较大的列表,并且您希望将其划分为较小的部分,然后对这些子列表执行一些操作。因此,使用该chunked功能可以轻松实现这一点。

val numList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val chunkedLists = numList.chunked(3)
print(chunkedLists) // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

制作数组的副本

您可以使用各种功能复制现有数组,例如:

copyInto:这会将一个数组的元素替换为另一个数组,或者如果目标数组由于大小限制或索引超出范围而无法保存原始数组的元素,则会引发异常。
val arrayOne = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val arrayTwo = arrayOf(11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
arrayOne.copyInto(destination = arrayTwo, destinationOffset = 2, startIndex = 0, endIndex = 4)
arrayTwo.forEach {print("$it ")} // 11 12 1 2 3 4 17 18 19 20

同样,还有其他函数可用于复制数组的元素。例如:

  • copyOfRange(fromIndex, toIndex):返回一个新数组,它是原始数组指定范围的副本。

  • copyOf()copyOf(newSize):返回一个新数组,它是原始数组的副本,调整为给定的 newSize,或者如果未传递 newSize,则将复制整个数组。

  • 将集合类型更改为其他

    根据情况,您可以更改集合的类型。在这里,您可以通过创建新集合或引用旧集合来将一个集合的类型更改为另一种类型。例如:

    toIntArraytoBooleanArraytoLongArraytoShortArraytoByteArraytoDoubleArraytoListtoMaptoSettoPair等可用于将一个集合的类型更改为另一种类型。

    var uIntArray = UIntArray(5) { 1U }
    var intArray = uIntArray.toIntArray()
    intArray[0] = 0
    print(uIntArray.toList()) // [1, 1, 1, 1, 1]
    print(intArray.toList()) // [0, 1, 1, 1, 1]
    

    在这里,我们正在制作一个新集合,新集合中的更改不会反映在旧集合中。但是,与此同时,您可以通过保留对旧集合的引用来更改集合的类型,即一个集合中的更改将自动反映在另一个集合中。为此to,我们需要使用as. 例如:

    asIntArrayasLongArrayasShortArrayasByteArrayasList等。

    var uIntArray = UIntArray(5) { 1U }
    var intArray = uIntArray.asIntArray()
    intArray[0] = 0
    print(uIntArray.toList()) // [0, 1, 1, 1, 1]
    print(intArray.toList()) // [0, 1, 1, 1, 1]
    

    使用某个键关联数据

    使用某个键关联数据

    如果您有一个数据列表,并且希望借助数据元素中存在的某些键来关联数据,那么您可以使用associateBy.

    data class Contact(val name: String, val phoneNumber: String)
    val contactList = listOf(
        Contact("Amit", "+9199XXXX1111"),
        Contact("Ali", "+9199XXXX2222"),
        Contact("Himanshu", "+9199XXXX3333"),
        Contact("Sumit", "+9199XXXX4444")
    val phoneNumberToContactMap = contactList.associateBy { it.phoneNumber }
    print(phoneNumberToContactMap)
    // Map with key: phoneNumber and value: Contact
    //     +9199XXXX1111=Contact(name=Amit, phoneNumber=+9199XXXX1111),
    //     +9199XXXX2222=Contact(name=Ali, phoneNumber=+9199XXXX2222),
    //     +9199XXXX3333=Contact(name=Himanshu, phoneNumber=+9199XXXX3333),
    //     +9199XXXX4444=Contact(name=Sumit, phoneNumber=+9199XXXX4444)
    

    在上面的例子中,key 是 phoneNumber,value 是 Contact。如果您不想将整个 Contact 作为值,那么您可以像这样简单地传递所需的值:

    val phoneNumberToContactMap = contactList.associateBy({it.phoneNumber}, {it.name})
    print(phoneNumberToContactMap)
    // Map with key: phoneNumber and value: name
    //     +9199XXXX1111=Amit, 
    //     +9199XXXX2222=Ali, 
    //     +9199XXXX3333=Himanshu, 
    //     +9199XXXX4444=Sumit}
    

    在集合中查找不同的元素

    我们可以使用 distinct 函数来获取集合中唯一元素的列表。

    val list = listOf(1, 2, 2, 3, 3, 3, 4, 4, 4, 4)
    println(list.distinct()) // [1, 2, 3, 4]
    

    您可以使用该union函数获取两个集合的唯一元素。两个集合的元素顺序将被保留,但第二个集合的元素将添加在第一个集合的元素之后。

    val listOne = listOf(1, 2, 3, 3, 4, 5, 6)
    val listTwo = listOf(2, 2, 4, 5, 6, 7, 8)
    println(listOne.union(listTwo)) // [1, 2, 3, 4, 5, 6, 7, 8]
    

    集合的交集

    要获取两个集合中共有的元素,您可以使用intersect返回包含两个集合的公共元素的集合的函数。

    val listOne = listOf(1, 2, 3, 3, 4, 5, 6)
    val listTwo = listOf(2, 2, 4, 5, 6, 7, 8)
    println(listOne.intersect(listTwo)) // [2, 4, 5, 6]
    

    只保留指定的元素

    如果在集合中,您只想保留指定的元素,那么您可以使用retainAll函数。由于此函数会修改您的列表,因此请确保您的列表或数组是可变的。

    retainAll如果从集合中删除任何元素,则返回 true,否则返回 false。

    val listOne = mutableListOf(1, 2, 3, 3, 4, 5, 6)
    val listTwo = listOf(1, 2, 3, 3, 4, 5, 6)
    val listThree = listOf(1, 2, 3, 3, 4, 5, 7)
    println(listOne.retainAll(listTwo)) // false
    println(listOne.retainAll(listThree)) // true
    println(listOne) // [1, 2, 3, 3, 4, 5]
    

    同样,您可以使用removeAll删除一个集合中存在于另一个集合中的所有元素。

    根据某些条件过滤集合

    您可以filter使用过滤器根据特定条件进行集合。这将返回一个列表,其中包含满足给定条件的元素。

    val list = listOf(1, 2, 3, 4, 5, 6, 7, 8)
    val filteredList = list.filter { it % 2 == 0 }
    print(filteredList) // [2, 4, 6, 8]
    

    同样,您可以使用 . 根据元素的索引过滤集合filterIndexed

    如果要将过滤后的元素存储在某个集合中,则可以使用filterIndexedTo

    val list = listOf(1, 2, 3, 4, 5, 6, 7, 8)
    val filteredList = mutableListOf<Int>()
    list.filterIndexedTo(filteredList) { index, i -> list[index] % 2 == 0 }
    print(filteredList) // [2, 4, 6, 8]
    

    您还可以使用 . 查找集合中指定类型实例的元素filterIsInstance

    val mixedList = listOf(1, 2, 3, "one", "two", 4, "three", "four", 5, 6, "five", 7)
    val strList = mixedList.filterIsInstance<String>()
    print(strList) // [one, two, three, four, five]
    

    zip返回对的列表。该对的第一个元素将从第一个集合中获取,而该对的第二个元素将从第二个集合中获取。返回列表的大小将等于最短集合的大小。

    val listOne = listOf(1, 2, 3, 4, 5)
    val listTwo = listOf("a", "b", "c", "d", "e", "f")
    print(listOne zip listTwo) // [(1, a), (2, b), (3, c), (4, d), (5, e)]
    

    与集合中的下一个一起压缩

    zipWithNext返回对的列表。该对的元素将是集合的相邻元素。

    val list = listOf(1, 2, 3, 4, 5)
    print(list.zipWithNext()) // [(1, 2), (2, 3), (3, 4), (4, 5)]
    

    解压缩集合

    unzip返回一对列表。第一个列表由每对的第一个元素组成,第二个列表由每对的第二个元素组成。

    val list = listOf("Amit" to 8, "Ali" to 10, "Sumit" to 4, "Himanshu" to 2)
    val (players, footballSkills) = list.unzip()
    print(players) // [Amit, Ali, Sumit, Himanshu]
    print(footballSkills) // [8, 10, 4, 2]
    

    根据某些条件将数组拆分为两部分

    如果您想根据某些条件(例如 isFootballFan)将数据拆分为两部分,则可以使用partition.

    data class User(val id: Int, val name: String, val isFootballLover: Boolean)
    val users = listOf(
        User(1, "Amit", true),
        User(2, "Ali", true),
        User(3, "Sumit", false),
        User(4, "Himanshu", false)
    val (footballLovers, nonFootballLovers) = users.partition { it.isFootballLover }
    print(footballLovers) // [User(id=1, name=Amit, isFootballLover=true), User(id=2, name=Ali, isFootballLover=true)]
    print(nonFootballLovers) // [User(id=3, name=Sumit, isFootballLover=false), User(id=4, name=Himanshu, isFootballLover=false)]
    

    您可以使用reversedandasReversed函数在 Kotlin 中反转列表。

    val list = listOf(1, 2, 3, 4, 5)
    print(list.reversed()) // [5, 4, 3, 2, 1]
    print(list.asReversed()) // [5, 4, 3, 2, 1]
    

    两者都提供相同的输出,但这些功能不同。

    reversed()函数可应用于 Array、List 和 MutableList。它生成一个与原始列表相反的新列表。

    但该asReversed()功能可以应用于 List 和 MutableList。它不会生成新列表,因为在反转之后,新元素仍然引用旧元素。因此,其中一个的任何变化都会导致另一个的变化。

    同样,还有其他函数可用于反转元素,例如reversedArray(), reverse()

    根据某些条件对集合的元素进行分组

    您可以使用groupBy()基于特定条件对集合的元素进行分组。例如,下面的代码将根据除以 4 时的余数对列表的元素进行分组,即有 4 个组(当余数 = 0、1、2 和 3 时)

    val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    print(list.groupBy { it % 4 })
    //     1=[1, 5, 9], 
    //     2=[2, 6, 10], 
    //     3=[3, 7], 
    //     0=[4, 8]
    

    对集合的元素进行排序

    您可以使用该sorted()函数对集合的元素进行排序。这将返回一个排序列表。

    val list = listOf(10, 4, 1, 3, 7, 2, 6)
    print(list.sorted()) // [1, 2, 3, 4, 6, 7, 10]
    

    同样,还有其他函数可用于根据特定条件对集合进行排序。其中一些函数是sortedArraysortedArrayWithsortedBysortedByDescendingsortedArraydescendingsortedWith等。