1、來了老弟?
2、映射为List: map{},mapIndexed{},mapNotNull{},mapIndexedNotNull{}
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
//[3, 6, 9]
println(numbers.mapIndexed { idx, value -> value * idx })
//[0, 2, 6]
3、双路合并
(1)zip()将两个集合中具有相同位置的元素构建配对。
val list1 = listOf(1, 2, 3)
val list2 = listOf("a", "b", "c")
val list = list1.zip(list2)
println(list)
//[(1, a), (2, b), (3, c)]
val list3 = list1.zip(list2) { l1, l2 -> "${l1}----${l2}" }
println(list3)
//[1----a, 2----b, 3----c]
(2)反向转换unzip(),list.unzip()得到一个Pair对象
val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
println(numberPairs.unzip())
//([one, two, three, four], [1, 2, 3, 4])
4、关联
根据集合元素和与其关联的某些值构建 Map。
(1) Map associateWith() 。其中原始集合的元素是键,值来自给定的转换函数。 如果两个元素相等,则仅保留最后一个。
val numbers = listOf("one", "two", "three", "four")
val map = numbers.associateWith { it.length }
println(map)
//{one=3, two=3, three=5, four=4}
(2) associateBy()。 键来自给定的转换函数,原始集合中的元素是值。也可以使用keySelector和valueTransform设置键和值。两个元素相等,则仅保留最后一个。
val numbers = listOf("one", "two", "three", "four")
println(numbers.associateBy { it.first().toUpperCase() })
//{O=one, T=three, F=four}
println(numbers.associateBy(keySelector = { it.first().toUpperCase() }, valueTransform = { it.length }))
//{O=3, T=5, F=4}
(3)associate()。键和值都是根据集合元素生成的。associate() 会生成临时的 Pair 对象,这可能会影响性能。
data class FullName(val firstName: String, val lastName: String)
fun parseFullName(fullName: String): FullName {
val nameParts = fullName.split(" ")
if (nameParts.size == 2) {
return FullName(nameParts[0], nameParts[1])
} else throw Exception("Wrong name format")
}
val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
println(names.associate { name -> parseFullName(name).let { it.lastName to it.firstName } })
//{Adams=Alice, Brown=Brian, Campbell=Clara}
5、打平
flatMap()可以打平集合中对象的某个类型为list的字段的值。
data class StringContainer(val values: List<String>)
val containers = listOf(
StringContainer(listOf("one", "two", "three")),
StringContainer(listOf("four", "five", "six")),
StringContainer(listOf("seven", "eight"))
)
println(containers)
//[StringContainer(values=[one, two, three]), StringContainer(values=[four, five, six]), StringContainer(values=[seven, eight])]
println(containers.flatMap { it.values })
//[one, two, three, four, five, six, seven, eight]
//即可以打平集合中对象的某个类型为list的字段的值
6、字符串表示
(1)joinToString() 根据提供的参数从集合元素构建单个 String。
val numbers = listOf("one", "two", "three", "four")
println(numbers)
//[one, two, three, four]
println(numbers.joinToString())
//one, two, three, four
println(numbers.joinToString("-", "开始", "结束"))
//开始one-two-three-four结束
println(numbers.joinToString("-", "开始", "结束", 3))
//开始one-two-three-...结束
println(numbers.joinToString("-", "开始", "结束", 3, "等等"))
//开始one-two-three-等等结束
println(numbers.joinToString("-", "开始", "结束", 3, "等等", { it -> it.toUpperCase() }))
//开始ONE-TWO-THREE-等等结束
(2)joinTo() 执行相同的操作,但将结果附加到给定的 Appendable (可追加的)对象。
val numbers = listOf("one", "two", "three", "four")
val listString = StringBuffer("The list of numbers: ")
numbers.joinTo(listString, "-", "开始", "结束", 3, "等等", { it -> it.toUpperCase() })
println(listString)
//The list of numbers: 开始ONE-TWO-THREE-等等结束
7、过滤
(1)filter()。只能检查集合中元素的值。
val numbers = listOf("one", "two", "three", "four")
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)
//[three, four]
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10 }
println(filteredMap)
//{key11=11}
(2)filterIndexed()。可以检查元素的索引和元素的值。
val numbers = listOf("one", "two", "three", "four")
val filteredIdx = numbers.filterIndexed { index, value -> (index != 0) && (value.length < 5) }
println(filteredIdx)
//[two, four]
(3) filterNot()。使用否定条件来过滤集合。
val numbers = listOf("one", "two", "three", "four")
val filteredNot = numbers.filterNot { it.length <= 3 }
println(filteredNot)
//[three, four]
(4)filterIsInstance<T>() 返回给定类型的集合元素。
val numbers = listOf(null, 1, "two", 3.0, "four")
println(numbers.filterIsInstance<String>())
//[two, four]
(5)filterNotNull() 返回所有的非空元素。在一个 List<T?> 上被调用时,filterNotNull() 返回一个 List<T: Any>。
val numbers = listOf(null, "one", "two", null)
println(numbers.filterNotNull())
//[one, two]
8、划分
partition() – 根据集合中元素的值进行过滤,并且返回一个Pair<List,List>。第一个list表示符合条件的集合;第二个list表示不符合条件的集合。
val numbers = listOf("one", "two", "three", "four")
val (match, rest) = numbers.partition { it.length > 3 }
println(match)
//[three, four]
println(rest)
//[one, two]
9、集合元素检查
(1)
如果至少有一个元素匹配给定谓词,那么 any() 返回 true。
如果没有元素与给定谓词匹配,那么 none() 返回 true。
如果所有元素都匹配给定谓词,那么 all() 返回 true。注意,在一个空集合上调用 all() 始终都会返回 true 。
val numbers = listOf("one", "two", "three", "four")
println(numbers.any { it.endsWith("e") })
//true
println(numbers.none { it.endsWith("a") })
//true
println(numbers.all { it.endsWith("e") })
//false
println(emptyList<Int>().all { it > 5 })
//true
(2)当any() 和 none()不设置条件时, 它们只是用来检查集合是否为空。 如果集合中有元素(即使是null),any() 返回 true,否则返回 false;none() 则相反
10、集合加减:plus与minus
val numbers = listOf("one", "two", "three", "three", "four")
//集合加和,第二个操作数可以是集合,也可以是元素
val plusList = numbers + "five"
println(plusList)
//[one, two, three, three, four, five]
//如果第二个操作数是一个集合,那么移除其元素在原始集合中的 所有 出现。
val minusList1 = numbers - listOf("three")
println(minusList1)
//[one, two, four]
//如果第二个操作数是一个元素,那么 minus 移除其在原始集合中的 第一次 出现
val minusList2 = numbers - "three"
println(minusList2)
//[one, two, three, four]
11、分组
(1) groupBy()
val numbers = listOf("one", "two", "three", "four", "five")
//根据转换函数得到key,value来自于集合的元素
println(numbers.groupBy { it.first().toUpperCase() })
//{O=[one], T=[two, three], F=[four, five]}
//根据转换函数得到key,value来自于对原有集合元素的转换结果
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.toUpperCase() }))
//{O=[one], T=[two, three], F=[four, five]}
(2) grouping()
在分组后,对所有的分组进行一次操作。eachCount() 计算每个组中的元素。还有fold()、reduce()、aggregate()等。
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.groupingBy { it.first() }.eachCount())
//{o=1, t=2, f=2, s=1}
12、取集合的一部分
(1)slice() 返回给定索引处的集合元素列表。
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.slice(1..3))
//[two, three, four]
println(numbers.slice(0..4 step 2))
//[one, three, five]
println(numbers.slice(setOf(3, 5, 0)))
//[four, six, one]
(2)take和drop
val numbers = listOf("one", "two", "three", "four", "five", "six")
//从头开始获取指定数量的元素
println(numbers.take(3))
//[one, two, three]
//从尾部开始获取指定数量的元素
println(numbers.takeLast(3))
//[four, five, six]
//从头开始去除给定数量的元素
println(numbers.drop(1))
//[two, three, four, five, six]
//从尾部开始去除给定数量的元素
println(numbers.dropLast(5))
//[one]
(3)takeWhile()和dropWhile()
val numbers = listOf("one", "two", "three", "four", "five", "six")
//不停地获取元素,直到遇到使表达式为false的首个元素。如果首个集合元素便使表达式为false,则结果为空。
println(numbers.takeWhile { !it.startsWith('f') })
//[one, two, three]
//从尾部开始,如上
println(numbers.takeLastWhile { it != "three" })
//[four, five, six]
//不停地删除元素,直到遇到使表达式为false的首个元素,然后返回剩余的元素。如果首个集合元素便使表达式为false,则返回集合所有的元素。
println(numbers.dropWhile { it.length == 3 })
//[three, four, five, six]
//从尾部开始,如上
println(numbers.dropLastWhile { it.contains('i') })
//[one, two, three, four]
(4)chunked()
将集合分为指定大小的子集
val numbers = (0..13).toList()
println(numbers.chunked(3))
//[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]
val numbers = (0..13).toList()
//将集合切割成指定大小的子集后,对子集元素进行转换
println(numbers.chunked(3) { it.sum() })
//[3, 12, 21, 30, 25]
(5)windowed()
val numbers = listOf("one", "two", "three", "four", "five")
//检索指定大小的所有可能子集
println(numbers.windowed(3))
//[[one, two, three], [two, three, four], [three, four, five]]
//设置步长
println(numbers.windowed(3, 2))
//[[one, two, three], [three, four, five]]
//partialWindows为true时,即使剩余的元素数量小于窗口长度,也会返回结果
println(numbers.windowed(3, 2, true))
//[[one, two, three], [three, four, five], [five]]
//对得到的所有子集进行转换
println(numbers.windowed(3, 2, true, { list -> list.map { it.toUpperCase() } }))
//[[ONE, TWO, THREE], [THREE, FOUR, FIVE], [FIVE]]
(6)zipWithNext()
val numbers = listOf("one", "two", "three", "four", "five")
//从头开始,返回所有的相邻元素对(Pair)
println(numbers.zipWithNext())
//[(one, two), (two, three), (three, four), (four, five)]
//s1,s2即相邻元素对
println(numbers.zipWithNext { s1, s2 -> s1.length > s2.length })
13、取单个元素
(1)elementAt()获取指定索引处的元素
val str = linkedSetOf("one", "two", "three", "four", "five").elementAt(3)
(2)elementAtOrNull()
val numbers = listOf("one", "two", "three", "four", "five")
//越界后返回null
println(numbers.elementAtOrNull(5))
//null
(3)elementAtOrElse()
val numbers = listOf("one", "two", "three", "four", "five")
//越界后返回lambda表达式的结果
println(numbers.elementAtOrElse(5) { index -> "The value for index $index is undefined" })
//The value for index 5 is undefined
(4)first()和last()
first()和last()也可以根据表达式查找。但是如果没有查找到目标元素,将会抛出异常。用 firstOrNull() 和 lastOrNull()替代,如果没有找到,会返回null。
可以使用find() 代替 firstOrNull();使用 findLast() 代替 lastOrNull()
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.first { it.length > 3 })
//three
println(numbers.last { it.startsWith("f") })
//five
(5) random()
随机返回一个元素。对于空集合会抛出异常。可以使用randomOrNull()替代,会返回null。
14、排序
(1)sortedWith(comparator: Comparator<in T>)
//compareBy()可根据给定的lambda表达式返回Comparator
println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length }))
//[c, bb, aaa]
(2) sorted() 和 sortedDescending()
val numbers = listOf("one", "two", "three", "four")
//自然升序
println(numbers.sorted())
//[four, one, three, two]
//自然降序
println(numbers.sortedDescending())
//[two, three, one, four]
(3) sortedBy(lambda表达式) 和 sortedByDescending(lambda表达式)
val numbers = listOf("one", "two", "three", "four")
val sortedNumbers = numbers.sortedBy { it.length }
println(sortedNumbers)
//[one, two, four, three]
val sortedByLast = numbers.sortedByDescending { it.last() }
println(sortedByLast)
//[four, two, one, three]
(4)reversed()和asReversed()
var numbers = mutableListOf("one", "two", "three", "four")
//返回原有集合的倒序副本,且和原有集合没有关联
println(numbers.reversed())
//[four, three, two, one]
//返回原有集合的倒序视图,且和原有集合相关联。即改变原有的集合,已得到的倒序视图会发生改变。
val reversedNumbers = numbers.asReversed()
println(reversedNumbers)
//[four, three, two, one]
numbers.add("five")
println(reversedNumbers)
//[five, four, three, two, one]
(5)shuffled()
返回一个以随机顺序排列的含有原有集合元素的新list
val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled())
15、聚合
(1)聚合操作如min()、max()、average()、sum()这些都只是对于数字类型的集合可用。count()计算集合中元素数量。
minBy{}、maxBy{}接收一个表达式;minWith{}、maxWith{}接收一个Comparator对象,可以由compareBy{}产生。
sumBy{}、sumByDouble{}接收一个表达式。前者对int类型的元素求和,并返回int。后者对Double类型的元素求和,并返回Double。
(2)fold()和reduce()。以及OrNull版本。
val numbers = listOf(5, 1, 3, 2)
//第一步的两个操作数分别是集合中第一个和第二个元素。(则第一个元素无法乘以2)
println(numbers.reduce { sum, element -> sum + element * 2 })
//17
//为sum设置了初始值。每一次的操作数都是sum和当前的集合元素。(可以保证每一个元素都乘以2)
println(numbers.fold(0) { sum, element -> sum + element * 2 })
//22
(3) reduceRight() 和 foldRight()从尾部开始进行计算。以及OrNull版本。
(4)foldIndexed()和reduceIndexed()将元素索引作为参数进行操作。以及OrNull版本。
val numbers = listOf(5, 2, 10, 4)
println(numbers.foldIndexed(0) { idx, sum, element -> if (idx % 2 == 0) sum + element else sum })
//15
println(numbers.reduceIndexed { idx, sum, element -> if (idx % 2 == 0) sum + element else sum })
//15
(5)reduceRightIndexed() 与 foldRightIndexed()从尾部开始进行计算。以及OrNull版本。
16、List操作
(1)getOrElse()、getOrNull()
val numbers = listOf(1, 2, 3, 4)
//越界时,返回null
println(numbers.getOrNull(5))
//越界时,返回表达式的结果,it等于index
println(numbers.getOrElse(6, { it }))
(2) indexOf() 返回元素第一个位置。 lastIndexOf() 返回元素最后一个位置。
(3)indexOfFirst() 和 indexOfLast() 可以接收一个表达式。
(4)二分查找 binarySearch()
要求该列表按照一定的顺序(自然排序或函数参数中提供的另一种排序)按升序排序过。
查询失败将返回 (-insertionPoint - 1),其中 insertionPoint 为应插入此元素的索引,以便列表保持排序。
如果存在多个目标元素返回其任一索引。
val numbers = mutableListOf("one", "two", "three", "four")
numbers.sort()
println(numbers)
//four, one, three, two]
println(numbers.binarySearch("two"))
// 3
println(numbers.binarySearch("z"))
// -5
println(numbers.binarySearch("two", 0, 2))
// -3
(5)通过Comparator使用二分查找
data class Product(val name: String, val price: Double)
val productList = listOf(
Product("WebStorm", 49.0),
Product("AppCode", 99.0),
Product("DotTrace", 129.0),
Product("ReSharper", 149.0))
println(productList.binarySearch(Product("AppCode", 99.0), compareBy<Product> { it.price }.thenBy { it.name }))
(6)fill()将集合中所有元素更新为指定值
val numbers = mutableListOf(1, 2, 3, 4)
numbers.fill(3)
println(numbers)
//[3, 3, 3, 3]
17、set操作
(1)union()获取并集。对于有序集合,操作数顺序决定元素顺序。a union b
(2)intersect()获取交集。a intersect b
(3)subtract()获取差集。a subtract b
18、map操作
filter()、filterKeys()、filterValues()
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10 })
//{key11=11}
println(numbersMap.filterKeys { it.endsWith("1") })
//{key1=1, key11=11}
println(numbersMap.filterValues { it < 10 })
//{key1=1, key2=2, key3=3}