本文会介绍一些 Kotlin 集合函数,这些函数可以极大地提高我们的开发效率,可以作为小抄随时翻阅~
删除array中重复的字符串
有很多方式可以从数组里移除重复的字符串:
// 保留元素的原始顺序
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.distinct()) // [Amit, Ali, Sumit, Himanshu]
// 保留元素的原始顺序
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.toSet()) // [Amit, Ali, Sumit, Himanshu]
// 保留元素的原始顺序
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.toMutableSet()) // [Amit, Ali, Sumit, Himanshu]
// 不保留元素的原始顺序
val devs = arrayOf("Amit", "Ali", "Amit", "Sumit", "Sumit", "Himanshu")
print(devs.toHashSet()) // [Amit, Ali, Sumit, Himanshu]
**将array 转为 list 或者 string **
你可以使用joinToString
函数将 list 转为字符串。例如, 有一个城市列表(Delhi, Mumbai, Bangalore),,然后你可以把列表转为这样的字符串: “India is one the best country for tourism. You can visit Delhi, Mumbai, Bangalore, etc, and enjoy your holidays”.
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 还有很多很棒的函数,比如 distinct, map, isEmpty, 等等
把一个集合转为单个结果
如果你想把一个给定的集合转换为单个结果,可以使用 rudece
函数。例如你可以对列表里所有元素求和:
val numList = listOf(1, 2, 3, 4, 5)
val result = numList.reduce { result, item ->
result + item
}
print(result) // 15
// 注意:如果列表是空的,会抛出RuntimeException
判断所有元素是否满足特定条件
如果你有一个数组或者列表,你想了解其中的所有元素是否全部满足某个条件,可以使用all
函数:
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
找到一个能够满足给定条件的元素
你可以使用find
函数在列表里找到一个满足给定条件的元素。比如,在一个学生列表中找到id是5的学生。find
函数会返回匹配给定条件的第一个元素,如果没有找到,会返回 null
。
single
函数会返回匹配给定条件的唯一元素,如果有多个元素满足条件或者没有满足条件的元素,会抛出异常:
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]]
复制数组
你可以使用这些函数实现对已有数组的复制:
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
类似地,还有其他的函数可以实现数组元素的复制,例如:
改变集合的类型
你可以视情况改变集合的类型。 你可以通过引用旧集合来新建一个其他类型的集合:
toIntArray, toBooleanArray, toLongArray, toShortArray, toByteArray, toDoubleArray, toList, toMap, toSet, toPair, 等函数可以改变集合的类型etc can be used to change the type of one collection to another type.
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]
这里我们创建了新集合并改变了新集合中的元素,这不会影响就集合。同时,我们也可以持有旧集合的引用来改变集合类型,改变一个集合就会影响到另外的那个集合。像这以as
前缀的函数:asIntArray, asLongArray, asShortArray, asByteArray, asList等等:
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]
将key与数据关联
如果你有一个列表数据,想把数据和数据中的key关联起来,可以使用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 作为value,那么可以像这样传你期望的值:
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)]
解压缩集合
unzup
函数返回一个列表二元组,元组中第一个列表由原集合中二元组的第一个元素组成,第二个元素由原集合二元组中第二个元组组成:
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]
将数组分成两部分
如果你想通过某些条件将一个数组分为两份,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)]
反转列表
reversed
函数和 asReversed
函数可以把列表反转。不同之处在于:reversed
可以应用在Array
, List
, and MutableList
上,函数返回一个反转后的新列表; asReversed
可以用于List
, and MutableList
上,函数返回的列表仍然引用旧列表,改变其中一个,会影响另一个列表:
val list = listOf(1, 2, 3, 4, 5)
print(list.reversed()) // [5, 4, 3, 2, 1]
print(list.asReversed()) // [5, 4, 3, 2, 1]
类似地,还有 reversedArray
,reverse
两个函数。
将集合元素分组
groupBy
函数可以把集合元素基于某个条件分组:
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]
除此之外,还有很多排序函数,如:sortedArray
, sortedArrayWith
, sortedBy
, sortedByDescending
, sortedArraydescending
, sortedWith
等等。