除了最通用的Array以外,kotlin中还有一类容器统称为Colletion(集合),他们有
- List
- List:继承Collection。一个范性有序的只读集合。因为有序,所以,我们可以使用get(position)等查询的方法
- MutableList:继承List,MutableCollection。一个有序集合。并额外提供了add/remove元素的方法
- Set
- Set:继承Collection。一个无序并不支持重复元素的集合
- MutableSet:继承Set,MutableCollection,一个无序的集合并且不支持重复元素。但是,支持add/remove元素
- Map
- Map:一个key-value的只读集合。并且key唯一。
- MutableMap:继承Map。支持put/remove元素
List
-
any:如果至少有一个元素与判断条件相符,则 返回true
-
all:如果全部元素与判断条件相符,则 返回true
-
component1,…,component5:返回集合的第n个元素,越界返回ArrayIndexOutOfBoundsException
-
contain:如果指定元素可以在集合找到,则 返回true
-
containsAll:如果指定集合所有元素都可以在目标集合找到,则 返回true
-
count:返回与判断条件相符的元素个数
-
distinct:返回一个只包含不同元素的数组,即对列表内元素去重
-
distinctBy:返回集合元素执行指定条件后,不同元素的数组(原始数组元素)
1
2val list = listOf(1, 4, 2, 2)
assertEquals(listOf(1,4),list.distinctBy { it%2 == 0}) -
drop:返回所有元素的列表,但不包含前n个元素
1
2val list = listOf(1,2,3,4)
assertEquals(listOf(3,4),list.drop(2)) -
dropLast:返回所有元素的列表,但不包含最后n个元素
1
2val list = listOf(1,2,3,4)
assertEquals(listOf(1,2),list.dropLast(2)) -
dropWhile:返回所有元素的列表,但不包含满足判断条件的元素
1
2
3
4val list = listOf(4,1,2,3,4)
assertEquals(listOf(4,1,2,3,4),list.dropWhile{it <3})
val list = listOf(1,2,3,4)
assertEquals(listOf(3,4),list.dropWhile{it <3}) -
elementAt:返回指定索引的元素,如果索引越界,则抛出ArrayIndexOutOfBoundsException
1
2
3
4
5
6
7
8val list = listOf(1,2,3,4)
assertEquals(4,list.elementAt(3))
// elementAtOrElse:返回指定索引的元素,如果索引越界,则返回指定的默认值
val list = listOf(1,2,3,4)
assertEquals(18,list.elementAtOrElse(6,{it *3}))
// elementAtOrNull: 返回指定索引的元素,如果索引越界,则返回null
val list = listOf(1,2,3,4)
assertEquals(null,list.elementAtOrNull(6)) -
filter:筛选出所有符合条件的元素
1
2
3
4
5
6
7
8
9
10
11
12
13val list = listOf(1,2,3,4)
assertEquals(listOf(2,3),list.filter{ it in 2..3 })
filterIndexed
// filterIndexed筛选出所有符合条件的元素(条件多了一个索引参数)
val list = listOf(1, 4, 2, 2)
assertEquals(listOf(4),list.filterIndexed { index, it -> index>0 && it >2} )
// filterNot: 筛选出所有不符合条件的元素
val list = listOf(1,2,3,4)
assertEquals(listOf(1,4),list.filterNot{ it in 2..3 })
filterNotNull
// filterNotNull: 筛选出所有不为null的元素
val list = listOf(1,2,3,null,4)
assertEquals(listOf(1,2,3,4),list.filterNotNull()) -
first
返回第一个满足条件的元素,没有则抛出NoSuchElementException
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22val list = listOf(1,2,3,4)
assertEquals(2,list.first { it > 1 })
// firstOrNull: 返回第一个满足条件的元素,没有,则 返回Null
val list = listOf(1, 2, 3, 4)
assertEquals(null, list.firstOrNull { it > 5 })
// find :同firstOrNull。返回第一个满足条件的元素,没有,则 返回Null
val list = listOf(1,2,3,4)
assertEquals(2,list.find { it > 1 })
// findLast: 返回最后一个满足条件的元素,没有,则 返回Null
val list = listOf(1,2,3,4)
assertEquals(4,list.findLast { it > 1 })
// last: 返回符合给定函数条件的最后一个元素,不存在则抛出NoSuchElementException
val list = listOf(1, 2, 2, 4)
assertEquals(4, list.last { it % 2 == 0 })
// lastIndexOf: 返回指定元素的第一个索引位置,不存在返回-1
val list = listOf(1, 2, 2, 4)
assertEquals(2, list.lastIndexOf(2) )
// lastOrNull: 返回符合给定函数条件的最后一个元素,不存在返回null
val list = listOf(1, 2, 2, 4)
assertNull( list.lastOrNull{ it >5}) -
single: 返回符合指定函数条件的单个元素,如果没有符合或者超过一个,则抛出异常。\
1
2
3
4
5
6val list = listOf(1, 2, 2, 4)
assertEquals(4, list.single { it == 4 })
// singleOrNull: 返回符合指定函数条件的单个元素,如果没有符合或者超过一个,则返回null
val list = listOf(1, 2, 2, 4)
assertEquals(null, list.singleOrNull { it == 2 }) -
flatMap: 遍历所有的元素,为每一个元素创建一个集合,最后把所有的集合放在一个集合中。
1
2val list = listOf(1, 2)
assertEquals(listOf(1,2,2,4),list.flatMap { it -> listOf(it,it*2) }) -
flatten: 遍历一个单独的集合,包含给定嵌套集合里面的所有元素。
1
2val list = listOf(listOf(1,2), listOf(4,2), listOf(3), listOf(4))
assertEquals(listOf(1,2,4,2,3,4), list.flatten()) -
fold: 将对集合从第一个到最后一个元素进行操作
1
2
3
4
5
6//这里是进行乘法操作
val list = listOf(1, 2, 3, 4)
assertEquals(48, list.fold(2) { total, next -> total * next })
// foldRight: 跟fold操作一样,不过是从最后一个到到一个元素进行操作
val list = listOf(1, 2, 3, 4)
assertEquals(48, list.foldRight(2) { total, next -> total * next }) -
reduce: 与fold功能一样。但是,没有初始值。把集合从第一个到最后一个,按指定条件进行操作
1
2val list = listOf(1, 2, 2, 4)
assertEquals(-7, list.reduce { total, next -> total -next }) -
get:获取索引所在的元素,没有则返回ArrayIndexOutOfBoundsException
1
2
3
4
5
6
7
8// getOrElse: 获取索引所在的元素,没有就返回默认值
val list = listOf(1, 2, 4, 2, 3, 4)
assertEquals(10, list.getOrElse(8, { _ -> 10 }))
assertEquals(2, list.getOrElse(1, { _ -> 10 }))
// getOrNull: 获取索引所在的元素,没有就返回nul
val list = listOf(1, 2, 4, 2, 3, 4)
assertEquals(null, list.getOrNull(8))
assertEquals(4, list.getOrNull(2)) -
map: 返回一个每个元素都根据给定函数条件转换的数组
1
2
3
4
5
6
7
8val list = listOf(1, 2, 2, 4)
assertEquals(listOf(2, 4, 4, 8), list.map{ it*2} )
// mapIndexed: 功能同map,比map多了一个索引
val list = listOf(1, 2, 2, 4)
assertEquals(listOf(0, 2, 4, 4), list.mapIndexed { index, it -> if (index % 2 == 0) index * it else it })
// mapNotNull: 同map。但是,元素转换不包含Null
val list = listOf(1, 2,null, 2, 4)
assertEquals(listOf(2, 4, 4, 8), list.mapNotNull { it?.times(2) }) -
max: 返回集合最大元素。不存在返回null
1
2
3
4
5
6
7
8
9
10
11
12
13
14val list = listOf(1, 2, 2, 4)
assertEquals(4, list.max())
val list = emptyList<Int>()
assertEquals(null, list.max())
// maxBy:返回根据指定函数转换后,产生的最大值的原始元素(返回的还是原始元素)。如果没有元素,则返回null。
val list = listOf(1, 2, 2, 4)
assertEquals(1, list.maxBy { -it })
// min:返回集合最小元素,不存在返回null
val list = listOf(1, 2, 2, 4)
assertEquals(1, list.min())
// minBy: 返回根据指定函数转换后,产生的最小值的原始元素(返回的还是原始元素)。如果没有元素,则返回null。
val list = listOf(1, 2, 2, 4)
assertEquals(4, list.minBy { -it }) -
none: 如果没有任何元素与指定的函数条件匹配,则返回true。
1
2val list = mutableListOf(1, 2, 2, 4)
assertTrue(list.none { it > 4 }) -
orEmpty: 如果没有任何元素与指定的函数条件匹配,则返回true。
1
2val list = mutableListOf(1, 2, 2, 4)
assertTrue(list.none { it > 4 }) -
sorted:返回所有元素分类排序列表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14val list = listOf(1, 4, 2, 2)
assertEquals(listOf(1, 2, 2, 4), list.sorted())
// sortBy:返回所有元素分类排序列表。顺序按照指定函数条件排列
val list = listOf(1, 4, 2, 2)
assertEquals(listOf(4,2,2,1), list.sortedBy { -it })
// sortDescending:返回所有元素分类排序列表。顺序按降序排列
val list = listOf(1, 4, 2, 2)
assertEquals(listOf(4,2,2,1), list.sortedDescending())
// sortedByDescending:返回所有元素分类排序列表。顺序按指定函数条件的降序排列
val list = listOf(1, 4, 2, 2)
assertEquals(listOf(1,2,2,4), list.sortedByDescending{ -it }) -
slice: 返回一个list中指定index的元素。
1
2
3val list = listOf(1, 4, 2, 2)
assertEquals(listOf(4,2,2), list.slice(1..3))
assertEquals(listOf(1,4), list.slice(listOf(0,1))) -
take: 返回从第一个元素开始的n个元素。
1
2val list = listOf(1, 4, 2, 2)
assertEquals(listOf(1,4), list.take(2)) -
zip: 返回一个列表,该列表由两个集合中相同索引元素建立的元素对。这个列表长度为最短集合的长度。
1 | val list = listOf(1, 4, 2, 2) |
-
groupBy
返回一个根据给定函数分组后的map, value为list
1
2val list = listOf(1, 2, 2, 4)
assertEquals(mapOf("error" to listOf(1), "right" to listOf(2, 2, 4)), list.groupBy { if (it % 2 == 0) "right" else "error" }) -
associateBy
通过指定的条件,把list转换成map,value为单元素
2种,第一只转换map的key;第二map的key-value都转换
1
2
3val list = listOf(1, 4, 2, 2)
assertEquals(hashMapOf("key1" to 1, "key4" to 4, "key2" to 2), list.associateBy { it -> "key" + it })
assertEquals(hashMapOf("key1" to "value1", "key4" to "value4", "key2" to "value2"), list.associateBy({ it -> "key" + it }, { it -> "value" + it }))
associateBy和groupBy区别
函数associateBy和groupBy构建来自由指定键索引的集合的元素的映射。key在keySelector参数中定义。
还可以指定可选的valueSelector来再选择定义将存储在map元素值中的内容。
区别
associateBy和groupBy之间的区别在于它们如何使用相同的键处理对象:
- associateBy使用最后一个合适的元素作为值。
- groupBy构建所有合适元素的列表并将其放入值中。
1 | data class StreamPractise( |
Map
-
getOrElse()
与 list 的工作方式相同:对于不存在的键,其值由给定的 lambda 表达式返回。 -
getOrDefault()
如果找不到键,则返回指定的默认值。 -
filter
: 可以使用filter()
函数来过滤 map 或其他集合。 对 map 使用filter()
函数时,Pair
将作为参数的谓词传递给它。 它将使用谓词同时过滤其中的键和值。1
2
3val 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) -
put()
添加新的kv -
putAll()
要一次添加多个条目,请使用putAll()
。它的参数可以是Map
或一组Pair
:Iterable
、Sequence
或Array
。1
2
3val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.putAll(setOf("four" to 4, "five" to 5))
println(numbersMap)remove
: 要从可变 Map 中删除条目,请使用remove()
函数。 调用remove()
时,可以传递键或整个键值对。 如果同时指定键和值,则仅当键值都匹配时,才会删除此的元素。
1
2
3
4
5val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.remove("one")
println(numbersMap)
numbersMap.remove("three", 4) //不会删除任何条目
println(numbersMap) -
plus
与minus
操作由于需要访问元素的键,
plus
(+
)与minus
(-
)运算符对 map 的作用与其他集合不同。plus
返回包含两个操作数元素的Map
:左侧的 Map 与右侧的 Pair 或另一个 Map 。 当右侧操作数中有左侧Map
中已存在的键时,该条目将使用右侧的值(覆盖)。1
2
3
4val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap + Pair("four", 4))
println(numbersMap + Pair("one", 10))
println(numbersMap + mapOf("five" to 5, "one" to 11))minus 将根据左侧 Map 条目创建一个新 Map ,右侧操作数带有键的条目将被剔除。 因此,右侧操作数可以是单个键或键的集合: list 、 set 等。
1
2
3val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap - "one")
println(numbersMap - listOf("two", "four")) -
containsKey, containsValue
-
isNotEmpty
-
sort map
:根据键或者值排序1
2
3
4
5
6
7val mmp = mapOf(1 to "aone", 3 to "three", 2 to "two", 4 to "four")
val sortedMap: SortedMap<Int, String> = mmp.toSortedMap(Comparator { o1, o2 ->
println("o1=$o1,o2=$o2")
if (o1 > o2) 1 else if (o1 < o2) -1 else 0
})
println(sortedMap) // {1=aone, 2=two, 3=three, 4=four} -
⭐️Convert Map to List
1
2
3
4
5
6
7
8val keyList = ArrayList(mmp.keys)
val valueList = ArrayList(mmp.values)
println("Key List: $keyList") // Key List: [1, 3, 2, 4]
println("Value List: $valueList") // Value List: [aone, three, two, four]
val list = mmp.toList().map { "${it.first}_${it.second}" }
println("list=$list") // list=[1_aone, 3_three, 2_two, 4_four] -
⭐️Converting a List to Map in Kotlin
1
2
3
4
5
6
7
8
9
10val user1 = User("John", 18, listOf("Hiking", "Running", "Reading"))
val user2 = User("Sara", 25, listOf("Chess", "Music"))
val user3 = User("Dave", 34, listOf("Games", "Programming"))
val myList = listOf(user1, user2, user3)
val myMap = myList.map { it.name to it }.toMap()
println(myMap) // {John=User(name=John, age=18, hobbit=[Hiking, Running, Reading]), Sara=User(name=Sara, age=25, hobbit=[Chess, Music]), Dave=User(name=Dave, age=34, hobbit=[Games, Programming])}
val amap = myList.associateBy { it.age }
println(amap) // {18=User(name=John, age=18, hobbit=[Hiking, Running, Reading]), 25=User(name=Sara, age=25, hobbit=[Chess, Music]), 34=User(name=Dave, age=34, hobbit=[Games, Programming])}
Author: Mrli
Link: https://nymrli.top/2021/12/27/Kotlin集合、流式操作/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.