Kotlin集合笔记

集合

1.集合的分类

list:是一个有序集合,通过索引来访问集合元素。元素可以在集合中出现多次。

set:集合中的元素是唯一的,一般来说set集合中的元素顺序并不重要。

map:是一组键值对,键是唯一的,每个键刚好映射到一个值,值是可以重复的。

2.集合的类型

kotlin标准库提供了基本集合类型的实现:set、list以及map。分为只读类型和可变类型。

只读类型是“型变“的,可变集合不是“型变”的。map在值(value)类型上是型变的,在键(key)类型上是不型变的。

    val list:List<CharSequence> = listOf<String>("hello")
//    val mutableList: MutableList = mutableListOf("hello")//error
	val map:Map<CharSequence, CharSequence> = mapOf<CharSequence,String>()//public interface Map
1.Collection

Collection是集合层次的根。

MutableCollection是具有写操作的Collection接口。

2.List

List以指定的顺序存储元素,并提供以索引访问元素的方法。List中的元素可以重复。

MutableList是可以进行写操作的List

kotlin中List的默认实现是ArrayList

3.Set

Set存储唯一的元素,它们的顺序通常是未定义的。null元素也是唯一的,一个Set集合只能包含一个null元素。

MutableSet是带有写操作的Set。

Set的默认实现是LInkedHashSet,保留元素的插入顺序。另一种实现HashSet,不声明元素的顺序。

由于Set的顺序是不确定的,所以它没有提供相应的按索引查找元素的方法。

4.Map

Map不是Collection接口的继承者。

MutableMap是具有写操作接口的Map.

Map的默认实现是LInkedHashMap,迭代Map时保留Map的插入顺序。

3.集合构造
1、由元素构造

listOf()、setOf()、mapOf(),mutableListOf()、mutableSetof()、mutableMapOf()。

    val set: Set<String> = setOf("hello", "world")
    val list  = mutableListOf("hello", "world")
    val map = mapOf<String, Int>("key1" to 1, "key2" to 2)
2、空集合

emptyList()、emptySet()、emptyMap(),创建的是只读属性的空集合。

    val eList = emptyList<String>()
    val eSet: Set<String> = emptySet()
    val eMap = emptyMap<String, Int>()
3、List的初始化构造函数

List接收大小和初始化函数的构造函数,该初始化函数根据所以定义元素的值。

    val list1 = List(3, { it + 2 })
    println(list1)
[2, 3, 4]
4、具体类型的构造函数
    val list2 = ArrayList<String>()
    val map2 = HashMap<String, Int>()
5、复制

创建与先由集合具有相同元素的集合。

toList()、toMutableList()、toMap()…,进行的是深复制的,创建了一个与原集合具有相同元素的新集合。

    val list = mutableListOf("hello", "world")
    val list3 = list.toList()
    list.add("good")
    println(list)
    println(list3)
[hello, world, good]
[hello, world]
6、可以使用只读属性的引用接收可变集合的对象,限制其可变性。
    val list = mutableListOf("hello", "world")
    list.add("good")
    val list4: List<String> = list
    list.add("hi")
    println(list4)
[hello, world, good, hi]
6、调用其他集合函数

如过滤生成新的与过滤器匹配的集合,映射生成转换集合列表,关联生成Map。

    val list6 = listOf("hi", "hello", "world", "boy")
    val list7 = list6.filter { it.length < 4 }
    println(list6)
    println(list7)
    val set2 = setOf(1, 2, 3)
    val set3 = set2.map { "value is $it" }
    println(set2)
    println(set3)
    val map3 = list6.associateWith { it.length }
    println(map3)
[hello, world, good, hi]
[hi, hello, world, boy]
[hi, boy]
[1, 2, 3]
[value is 1, value is 2, value is 3]
{hi=2, hello=5, world=5, boy=3}
4.迭代器

按顺序提供对元素的访问

1、Iterator

Iterable接口的继承者(包括Set和List)可通过方法iterator()获得迭代器。一旦迭代器通过最后一个元素,它就不能用于检索元素;迭代器也不能指向以前的元素。要再次检索集合,需重新创建新的迭代器。

    val list1 = listOf("hi", "hello", "world", "boy")
    val iter:Iterator<String> = list1.iterator()
    while (iter.hasNext()){//hasNext判断的是迭代的次数与集合大小是否相等,cursor != size
        //next一次,取出当前元素,迭代次数就+1,cursor = i + 1;return (E) elementData[lastRet = i];
        println(iter.next())
    }

for和forEach

    for (item in list1){
        println(item)
    }
    list1.forEach { println(it) }
2、List迭代器

对于列表,ListIterator支持双向迭代

    val listTer = list1.listIterator()
    while (listTer.hasNext()){
        print(listTer.next() + " ")
    }
    println()
    while (listTer.hasPrevious()){
        print(listTer.previous() + " ")
    }
    println()
hi hello world boy 
boy world hello hi 
3、可变迭代器

可变集合的迭代器,可以操作集合

删除操作,删除的是当前位置的前一个元素,所以remove()必须在next()之后。

    val list2 = mutableListOf("one", "two", "three")
    val iter2 = list2.iterator()
    iter2.next()
    iter2.remove()//iterator值提供了remove方法
    println(list2)
[two, three]

ListIterator还提供了插入和替换元素的方法,操作的是迭代器指向的当前位置

    val list3 = mutableListOf("one", "two", "three")
    println(list3)
    val iter3 = list3.listIterator()
    iter3.add("hi")
    iter3.next()
    println(list3)
    iter3.set("hello")
    println(list3)
[one, two, three]
[hi, one, two, three]
[hi, hello, two, three]
4.区间和数列

1、只有整数类型区间(IntRange、LongRange、CharRange)

    for (i in 0..5){
        print("$i ")
    }
    println()
0 1 2 3 4 5 

反向迭代 downTo

    for (i in 5 downTo 0){
        print("$i ")
    }
    println()
5 4 3 2 1 0 

任意步长迭代 step

    for (i in 5 downTo 0 step 2){
        print("$i ")
    }
    println()
5 3 1 

2、数列整数类型的区间可视为等差数列。

数列具有三个基本属性:first、last、step。后续元素是前一个元素加上step。

5.序列

序列(Sequence)提供了与Iterable相同的函数。

1、构造

由元素

val sq = sequenceOf<Int>(1, 2, 3)

由Iterable

    val list = listOf<Int>(1, 2, 3)
    val sq1 = list.asSequence()

由函数

可以将第一个元素指定为显式值或函数调用的结果。 当提供的函数返回 null 时,序列生成停止。因此,以下示例中的序列是无限的。

    val sq2 = generateSequence(1) { if(it < 20) it * 2 else null }
    println(sq2.toList())
[1, 2, 4, 8, 16, 32]

由组块

    val sq3 = sequence<Int> {
        yield(1)
        yieldAll(5..10)
        yieldAll(generateSequence(20) { it + 1 })
    }
    println(sq3.take(10).toList())
 [1, 5, 6, 7, 8, 9, 10, 20, 21, 22]   
2、序列操作

无状态

有状态

6.集合操作
1、映射

映射转换,从一个集合元素上的函数结果创建另一个集合。

    val set = setOf(1, 2, 3)
    val mSet = set.map { it * 2 }
    val mSet1 = set.mapIndexed{index, i ->
        index * i
    }
    val mNSet = set.mapNotNull { if (it == 2) null else it * 2 }
    println(mSet)
    println(mSet1)
    println(mNSet)
[2, 4, 6]
[0, 2, 6]
[2, 6]

Map集合即可转换值,也可转换键,调用map转换得到的是一个List集合

    val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3)
    val list: List<Int> = map.map { it.value }//list
    val map1: Map<String, Int> = map.mapKeys { it.key.uppercase() }
    val map2: Map<String, Int> = map.mapValues { it.value * 2 }
    println(list)
    println(map1)
    println(map2)
[1, 2, 3]
{KEY1=1, KEY2=2, KEY3=3}
{key1=2, key2=4, key3=6}
2、合拢

合拢转换,根据两个集合中相同位置的元素构建配对。zip()返回的是Pair对象的列表List(键值对列表)。只有继承了Iterable接口的List、Set集合和数组Array可以实现合拢,Map没有。

    val list1 = listOf("red", "brown", "grey")
    val animals = listOf("fox", "bear", "wolf")
    val twoAnimal = listOf("fox", "bear")
    val zList1 = list1 zip animals
    val zList2 = list1.zip(twoAnimal)
    list1.zip(animals){a, b -> println("$a  $b")}
red  fox
brown  bear
grey  wolf

要分割键值对列表,用unzip(),得到的是一个Pair对象,键为第一个列表,值为第二个列表。

    val unPair: Pair<List<String>, List<String>> = zList1.unzip()
    println(unPair.first)
    println(unPair.second)
[red, brown, grey]
[fox, bear, wolf]
3、关联

关联转换,允许集合元素与其关联的某些值构建Map集合。

associateWith(),创建一个Map,原始集合中的元素是键,转换函数返回值。

    val list = listOf("one", "two", "three", "four", "one")
    val map1 = list.associateWith { it.length }
    println(map1)
{one=3, two=3, three=5, four=4}

associateBy(),与associateWith()相反,集合元素为值,转换函数返回键,或者可以自定义key和value

    val map2 = list.associateBy { it.length }
    val map3 = list.associateBy(keySelector = { it.first().uppercase() },
        valueTransform = { it.length })
    println(map2)
    println(map3)
{3=one, 5=three, 4=four}
{O=3, T=5, F=4}

associate(),转换函数返回一个Pair对象。

    val map4 = list.associate { it to it.length }
    println(map4)
{one=3, two=3, three=5, four=4}
4、打平

就是将集合的集合中的集合拆开,生成一个新的集合。

flatten(),直接将集合中的集合拆开

    val list1: List<Set<Char>> = listOf(setOf('a', 'b'), setOf('c', 'd'), 
    setOf('e', 'f'))
    val list2: List<Char> = list1.flatten()
    println(list1)
    println(list2)
[[a, b], [c, d], [e, f]]
[a, b, c, d, e, f]

flatMap(),在集合拆开前可以将集合中的集合映射为另一个集合。

    val list3: List<Char> = list1.flatMap { it.map { it + 1 } }
    println(list3)
[b, c, d, e, f, g]
5、字符串表示

将集合转换为字符串的函数joinToString()、joinTo()

    val list = listOf("one", "two", "three")
    val listString1 = list.joinToString()
    println(listString1)
    val listString2 = StringBuilder("The list is: ")
    list.joinTo(listString2)
    println(listString2)
    val listString3 = list.joinToString(separator = " | ", prefix = "start ", postfix = " end")
    println(listString3)
    val listString4 = list.joinToString { "Element: ${it.uppercase()}" }
    println(listString4)
    val listString5 = (1..100).toList().joinToString(limit = 10, truncated = "<...>")
    println(listString5)
one, two, three
The list is: one, two, three
start one | two | three end
Element: ONE, Element: TWO, Element: THREE
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <...>
7.过滤集合

过滤条件为接受一个集合元素返回布尔值的lambda表达式,true表示给定元素匹配,false表示不匹配。

1、过滤

filter()

    val list = listOf("one", "two", "three", "four")
    val list1:List<String> = list.filter { it.length > 3 }
    println(list1)
    val map = mapOf("key1" to 1, "key2" to 2, "key12" to 12, "key13" to 13)
    val map1 = map.filter { (key, value) -> value > 10 && key.endsWith("2") }
    println(map1)
    val list2 = list.filterIndexed { index, s -> s.length > 4 && index > 1 }
    println(list2)
    val list3 = list.filterNot { it.length > 3 }//按否定条件过滤集合
    println(list3)
[three, four]
{key12=12}
[three]
[one, two]

filterIsInstance()

filterNotNull

    val list4: List<Any> = listOf(1, 'c', "hello", 1.3f, "world")
    val list5 = list4.filterIsInstance<String>()
    println(list5)
    val list6: List<String?> = listOf(null, "hello", null, "world")
    val list7: List<String> = list6.filterNotNull()
    println(list7)
[hello, world]
[hello, world]
2、划分

partition(),返回一个List的Pair对象,第一个List为匹配的元素集合,第二个为其他不匹配的元素集合。

    val (match, rest) = list.partition { it.length > 3 }
    println(match)
    println(rest)
[three, four]
[one, two]
3、检验

any(),至少有一个元素匹配

none(),没有元素匹配

all(),所有元素都匹配

    println(list.any { it.endsWith('e') })
    println(list.none { it.endsWith('e') })
    println(list.all { it.endsWith('e') })
true
false
false

any()和none()不带参数,只是检查集合是否为空。如果集合中有元素,any()返回true,none()则相反

    println(list.any())
    println(list.none())
    println("-------------")
    val eList = emptyList<String>()
    println(eList.any())
    println(eList.none())
true
false
-------------
false
true
8.加减操作

返回一个新的只读集合

    val list1 = mutableListOf("one", "two", "three", "four")
    val list2 = listOf("three", "four")
    val list3 = list1 + list2
    val list4 = list1 - list2
    val list5 = list1 + "five"
    val list6 = list1 - "one"
    println(list3)
    println(list4)
    println(list5)
    println(list6)
[one, two, three, four, three, four]
[one, two]
[one, two, three, four, five]
[two, three, four]
9.分组
1、基本函数groupBy()

使用一个Lambda表达式,返回一个Map。此Map中,键为LamBda表达式的结果,而对应的值是返回此结果的元素List。

    val list = listOf("one", "two", "three", "four", "five")
    val map1: Map<String, List<String>> = list.groupBy { it.first().uppercase() }
    val map2: Map<Char, List<String>> =
        list.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() })
    println(map1)
    println(map2)
    val map3 = mutableMapOf<Char, MutableList<String>>()
    list.groupByTo(map3, keySelector = { it.first() })
    println(map3)
{O=[one], T=[two, three], F=[four, five]}
{o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}
{o=[one], t=[two, three], f=[four, five]}
2、groupingBy()
    val map4 = list.groupingBy { it.first() }.eachCount()
    println(map4)
{o=2, t=2, f=2}
10.取集合的一部分
1、slice

返回给定索引的集合元素列表。

    val numbers = listOf("one", "two", "three", "four", "five", "six", "seven", "eight")
    val list1 = numbers.slice(setOf(1, 3, 5))
    println(list1)
    val list2 = numbers.slice(1..5)
    println(list2)
    val list3 = numbers.slice(1..6 step 2)
    println(list3)
[two, four, six]
[two, three, four, five, six]
[two, four, six]
2、take与drop

take获取指定数量的元素。

    val list4 = numbers.take(3)//从头开始
    println(list4)
    val list5 = numbers.takeLast(3)//从尾开始
    println(list5)
[one, two, three]
[six, seven, eight]

drop去除指定数量的元素

    val list6 = numbers.drop(3)
    println(list6)
    val list7 = numbers.dropLast(3)
    println(list7)
[four, five, six, seven, eight]
[one, two, three, four, five]

takeWhile(),从头开始,获取与条件相匹配的元素,直到不匹配元素为止

takeLastWhile(),从尾开始,获取与条件相匹配的元素,直到不匹配元素为止

dropWhile(),从头开始,去除与条件匹配的元素,直到匹配的元素为止

dropLastWhile(),从尾开始,去除与条件匹配的元素,直到匹配的元素为止

    val list8 = numbers.takeWhile { !it.startsWith('f') }
    println(list8)
    val list9 = numbers.takeLastWhile { !it.startsWith('f') }
    println(list9)
    val list10 = numbers.dropWhile { it.length <= 3 }
    println(list10)
    val list11 = numbers.dropLastWhile { it.length > 3 }
    println(list11)
[one, two, three]
[six, seven, eight]
[three, four, five, six, seven, eight]
[one, two, three, four, five, six]
3、chunked

将集合分解为给定大小的块。

    val list13 = numbers.chunked(3)
    println(list13)
    val list14 = numbers.chunked(3){ it.map { it.length } }
    println(list14)
[[one, two, three], [four, five, six], [seven, eight]]
[[3, 3, 5], [4, 4, 3], [5, 5]]
4、windowed

检索给定大小的集合元素中所用可能区间。

    val list15 = numbers.windowed(3)
    println(list15)
    val list16 = numbers.windowed(3, 2)
    println(list16)
    val list17 = numbers.windowed(3, partialWindows = true)
    println(list17)
    val list18 = numbers.windowed(3){ it.filter { it.length > 3 } }
    println(list18)
[[one, two, three], [two, three, four], [three, four, five], [four, five, six], [five, six, seven], [six, seven, eight]]
[[one, two, three], [three, four, five], [five, six, seven]]
[[one, two, three], [two, three, four], [three, four, five], [four, five, six], [five, six, seven], [six, seven, eight], [seven, eight], [eight]]
[[three], [three, four], [three, four, five], [four, five], [five, seven], [seven, eight]]

构建两个元素的窗口zipWithNext()

    val list19 = numbers.zipWithNext()
    println(list19)
    val list20 = numbers.zipWithNext { a, b -> a.length > b.length }
    println(list20)
[(one, two), (two, three), (three, four), (four, five), (five, six), (six, seven), (seven, eight)]
[false, false, true, false, true, false, false]
11.去单个元素
1、按位置取

elementAt()

对不提供索引访问的集合很有用

    val numberSet = linkedSetOf("one", "two", "three", "four", "five")
    println(numberSet.elementAt(3))
    val sortNumberSet = sortedSetOf("one", "two", "three", "four", "five")
    println(sortNumberSet.elementAt(3))
    println(numberSet.first())
    println(numberSet.last())
four
three
one
five

elementAtOrNull()

elementAtOrEles()

    val sortNumberSet1 = sortedSetOf(compareBy { it.length }, "one", "two", "three", "four", "five")
    println(sortNumberSet1)
    println(sortNumberSet1.elementAtOrNull(3))
    println(sortNumberSet1.elementAtOrElse(3){ "The value for index $it is undefined." })
[one, four, three]
null
The value for index 3 is undefined.
2、按条件取

first()、last()

    val numbers = listOf("one", "two", "three", "four", "five")
    println(numbers.first() { it.length > 3 })
    println(numbers.firstOrNull() { it.length > 5 })
three
null

find()、findLast()

    println(numbers.find { it.startsWith('f') })//调用的是firstOrNull()
    println(numbers.findLast { it.startsWith('f') })//调用的是lastOrNull()
    println(numbers.find { it.length > 5 })
four
five
null
3、随机取元素

random()

println(numbers.random())
4、检测存在与否

contains()/in,containsAll()

    println(numbers.contains("four"))
    println("one" in numbers)
    println(numbers.containsAll(listOf("one", "two")))
true
true
true

isEmpty()、isNotEmpty()

    println(numbers.isEmpty())
    println(numbers.isNotEmpty())
false
true
12.排序

如需自定义一个自然顺序的类,这个类需要继承Comparable接口。

class Version(val major: Int, val minor: Int) : Comparable<Version> {
    override fun compareTo(other: Version): Int {
        if (this.major != other.major) {
            return this.major - other.major
        } else if (this.minor != other.minor) {
            return this.minor - other.minor
        }
        return 0
    }
}

fun main() {
    println(Version(1, 0) > Version(1, 1))
    println(Version(1, 2) > Version(1, 0))
}
false
true

Compartor()/compareBy()

    val numbers = listOf("one", "two", "three", "four", "five")
    println(numbers.sortedWith(comparator = Comparator { o1, o2 -> o1.length - o2.length }))
    println(numbers.sortedWith(comparator = compareBy { it.length }))
[one, two, four, five, three]
[one, two, four, five, three]
1、自然顺序

sorted()/sortedDescending()

    println(numbers.sorted())
    println(numbers.sortedDescending())
    println(numbers)
[five, four, one, three, two]
[two, three, one, four, five]
[one, two, three, four, five]
2、自定义顺序

sortedBy()/sortedByDescending()

    println(numbers.sortedBy { it.first() })
    println(numbers.sortedByDescending { it.first() })
[four, five, one, two, three]
[two, three, one, four, five]

sortedWith()\

    println(numbers.sortedWith(comparator = Comparator { o1, o2 -> o1.first() - o2.first() }))

[four, five, one, two, three]
3、倒序

reversed(),返回带有元素副本的新集合

    println(numbers.reversed())
[five, four, three, two, one]

asReversed(),返回相同集合实例的反向视图,原集合更改反向视图也会更改。

    val mutableList = mutableListOf("one", "two", "three", "four", "five")
    val mutableList1 =mutableList.asReversed()
    mutableList[2] = mutableList[2].uppercase()
    println(mutableList)
    println(mutableList1)
    mutableList1[3] = mutableList1[3].uppercase()
    println(mutableList1)
    println(mutableList)
    mutableList.add("six")
    println(mutableList)
    println(mutableList1)
[one, two, THREE, four, five]
[five, four, THREE, two, one]
[five, four, THREE, TWO, one]
[one, TWO, THREE, four, five]
[one, TWO, THREE, four, five, six]
[six, five, four, THREE, TWO, one]
4、随机顺序

shuffled()

    println(numbers.shuffled())
    println(numbers.shuffled(random = Random(2)))
[two, five, one, three, four]
[four, one, three, two, five]
13.聚合操作
1、基本操作

min()/max(),返回最小/最大值

average(),返回平均值

sum(),返回数字集合中元素的总和

count(),返回集合中元素的个数

    val numbers = listOf(5, 42, 10, 4, 35)
    println(numbers.minOrNull())
    println(numbers.maxOrNull())
    println(numbers.average())
    println(numbers.sum())
    println(numbers.count())
4
42
19.2
96
5

也可以接受一个选择器函数或自定义Compartor来检索最大、最小值

    println(numbers.minByOrNull { it % 3 })
    println(numbers.minWithOrNull(comparator = Comparator { o1, o2 -> o1 % 3 - o2 % 3 }))
42
42

也可以接受一个函数,对所有调用此函数的返回值求和

    println(numbers.sumOf { it % 10 })
    println(numbers.sumOf { it.toDouble() / 10 })
16
9.600000000000001
2、fold与reduce

一次将所提供的操作应用于集合元素并返回累积结果。集合中不能有null

fold(),接受一个初始值并将其作为第一步的累积值

reduce(),第一步则将第一个和第二个元素作为第一步的操作参数

    val sum1 = numbers.fold(10) { sum, element -> sum + element }
    println(sum1)
    val sum2 = numbers.reduce { sum, element -> sum + element }//第一步sum是第一个元素,element是第二个元素,以后步骤sum是累加的和element是对应元素
    println(sum2)
106
96

foldRight()/reduceRight(),是从最后一个元素开始向前累积。第一个参数和第二参数与fold()/reduce()相反,第一个参数为集合元素,第二个参数为累积值

    val numbers1 = listOf(1, 2, 3, 4)
    val sum4 = numbers1.foldRight(10){ element, sum ->
        println("$element $sum")
        element + sum
    }
    println(sum4)
    println("--------------------")
    val sum5 = numbers1.reduceRight { element, sum ->
        println("$element $sum")
        element + sum
    }
    println(sum5)
4 10
3 14
2 17
1 19
20
--------------------
3 4
2 7
1 9
10

foldIndex()/reduceIndex()

    val sum6 = numbers1.foldIndexed(10){ index, sum, element ->
        println("$index $sum $element")
        if (index % 2 ==0) sum + element else sum
    }
    println(sum6)
14.集合写操作

可变集合支持改变集合的操作。实现MutableCollection接口的所有写操作。

1、添加元素

add(),单元素添加

addAll(),可以指定添加位置,参数可以是Iterable、Sequence或Array

+/+=,将元素或集合追加到集合的末尾

    val mutableList = mutableListOf(1, 2, 3, 4, 5)
//  mutableList.add(6)
//  mutableList.addAll(2, setOf(10, 11))
    val list = mutableList + 6
    println(mutableList)
    println(list)
    mutableList += 6
    println(mutableList)
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
2、删除元素

remove()

removeAll(),移除参数集合中存在的所有元素,也可根据传入的条件判断

retainAll(),与removeAll()相反,移除参数集合中元素之外的所有元素。

clear(),清空集合

-/-=

//    mutableList.removeAt(1)
//    mutableList.remove(5)
//    mutableList.removeAll(arrayOf(1,2))
    mutableList.removeAll { it > 3 }
    println(mutableList)
[1, 2, 3]
	mutableList.retainAll { it > 3 }
	println(mutableList)
[4, 5]
	val list1 = mutableList - 3
    println(list1)
    println(mutableList)
    mutableList -= 3
    println(mutableList)
[1, 2, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 4, 5]
15.List相关操作
1、按索引去元素

elementAt()、first()、last()。这是通过 get() 函数或简写语法 [index] 来传递索引参数完成的。

如果List长度小于指定索引,则抛出异常。getOrElse()、getOrNull()

    val list = listOf(1, 2, 3, 4, 5)
    val a = list.getOrElse(10){
        println(it)
        -1
    }
    println(a)
10
-1
    val b = list.getOrNull(10)
    println(b)
null
2、取列表的一部分

subList(),将指定元素范围的视图作为列表返回

    val mutableList = list.toMutableList()
    val subList = mutableList.subList(0, 2)
    println(mutableList)
    println(subList)
    println("-----------")
    mutableList.forEachIndexed { index, i ->
        mutableList[index] = i * 2
    }
    println(mutableList)
    println(subList)
[1, 2, 3, 4, 5]
[1, 2]
-----------
[2, 4, 6, 8, 10]
[2, 4]
3、查找元素位置

线性查找,indexOf()、lastIndexOf(),根据条件查找 indexOfFirst()、indexOfLast()

    val list = listOf(1, 2, 3, 4, 5)
    val i1 = list.indexOf(4)
    println(i1)
    val i2 = list.lastIndexOf(4)
    println(i2)
    val j1 = list.indexOfFirst { it > 3 }
    println(j1)
    val j2 = list.indexOfLast { it < 3 }
    println(j2)
3
3
3
1

有序列表中二分查找

要求列表必须是排好序的。

binarySearch(),返回为负,表示没找到

    val numbers = mutableListOf("one", "two", "three", "four")
    numbers.sort()
    println(numbers)
    println(numbers.binarySearch("two"))
    println(numbers.binarySearch("five"))
    println(numbers.binarySearch("two", 0, 2))//指定范围查找
[four, one, three, two]
3
-1
-3

Comparator二分查找

如果列表元素不是Comparable,则应提供一个用于二分查找的Comparator。

   class Fruit(val name: String, val price: Double)

    val fList = listOf(
        Fruit("apple", 10.0),
        Fruit("pear", 11.0),
        Fruit("banana", 15.0)
    )
    val f1 = fList.binarySearch(Fruit("grape", 11.0), compareBy<Fruit> { it.price })
    val f2 = fList.binarySearch(Fruit("grape", 11.0), Comparator { o1, o2 ->
        if (o1.price != o2.price){
            return@Comparator if (o1.price > o2.price) return@Comparator 1 else return@Comparator -1
        }else if (o1.name != o2.name){
            if (o1.name > o2.name) return@Comparator 1 else return@Comparator -1
        }
        return@Comparator 0
    })
    val f3 = fList.binarySearch(Fruit("grape", 11.0), compareBy<Fruit> { it.price }.thenBy { it.name })
    val f4 = fList.binarySearch(Fruit("pear", 11.0), compareBy<Fruit> { it.price }.thenBy { it.name })
    println(f1)
    println(f2)
    println(f3)
    println(f4)
1
-2
-2
1

比较函数二分查找

使用 比较 函数的二分搜索无需提供明确的搜索值即可查找元素。 取而代之的是,它使用一个比较函数将元素映射到 Int 值,并搜索函数返回 0 的元素。 该列表必须根据提供的函数以升序排序;换句话说,比较的返回值必须从一个列表元素增长到下一个列表元素。

    val search = fun(fruit: Fruit, price: Double): Int { return (fruit.price - price).toInt() }
    val search1 = { fruit: Fruit, price: Double -> (fruit.price - price).toInt() }
    val f5 = fList.binarySearch { (it.price - 10.0).toInt() }
    val f6 = fList.binarySearch { search(it, 10.0) }
    val f7 = fList.binarySearch { search1(it, 10.0) }
    println(f5)
    println(f6)
0
0
4、List写操作

可变列表支持特定的写操作

添加,add()、addAll()

    val numbers = mutableListOf("one", "five", "six")
    numbers.add(1, "two")
    println(numbers)
    numbers.addAll(2, listOf("three", "four"))
    println(numbers)
[one, two, five, six]
[one, two, three, four, five, six]

更新,set()/[]

fill(),将所有元素替换成指定的值

    val numbers = mutableListOf("one", "five", "six")
    numbers.set(1, "two")
    numbers[2] = "three"
    println(numbers)
[one, two, three]
    numbers.fill("six")
    println(numbers)
[six, six, six]

删除,removeAt()

    val numbers = mutableListOf("one", "five", "six")
	numbers.removeAt(0)
    println(numbers)
[five, six]
    val numbers = mutableListOf("one", "five", "six")
    numbers.removeFirst()
    println(numbers)
[five, six]
    val numbers = mutableListOf("one", "five", "six")
    numbers.removeLast()
    println(numbers)
[one, five]

排序,对集合本身进行排序,与12的排序类似,只是没有ed后缀

sort()

    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.sort()
    println(numbers)
    numbers.sortDescending()
    println(numbers)
    numbers.sortBy { it.length }
    println(numbers)
    numbers.sortByDescending { it.length }
    println(numbers)
	//thenBy()构造一个比较器,在主比较器判断相等的情况下,在根据thenBy()的条件进行判断
    numbers.sortWith(compareBy<String> { it.length }.thenBy { it })
    println(numbers)
[five, four, one, three, two]
[two, three, one, four, five]
[two, one, four, five, three]
[three, four, five, two, one]
[one, two, five, four, three]

shuffle(),将集合中的元素随机排序

    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.shuffle()
    println(numbers)
[three, four, five, one, two]

reverse()

    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.reverse()
    println(numbers)
[five, four, three, two, one]
16.Set相关操作

并集union

交集intersect

差集subtract

    val set1 = setOf("one", "two", "three")
    val set2 = setOf("one", "four", "five")
    val uSet = set1 union set2
    val iSet = set1 intersect set2
    val sSet = set1 subtract set2
    println(uSet)
    println(iSet)
    println(sSet)
[one, two, three, four, five]
[one]
[two, three]
    val list1 = listOf("one", "two", "two", "three")
    val list2 = listOf("one", "four", "five")
    val ulSet = list1 union list2
    val ilSet = list1 intersect  list2
    val slSet = list1 subtract list2
    println(ulSet::class)
    println(ulSet)
    println(ilSet)
    println(slSet)
class java.util.LinkedHashSet
[one, two, three, four, five]
[one]
[two, three]

List也支持Set操作,List进行Set操作的结果也是Set集合,因此结果中将删除List中重复的元素。

17.Map相关操作
1、取键与值

get/[],getValue()和get类似,只是如果不存在键时会报错。

    val numberMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    println(numberMap["one"])
    println(numberMap.getOrDefault("five", -1))//返回默认值
    println(numberMap.getOrElse("five", { -2 }))//返回Lambda的返回值
    println(numberMap["five"])//不存在返回null
    println(numberMap.getValue("two"))
    //println(numberMap.getValue("five"))//error
1
-1
-2
null
2

keys、values

    println(numberMap.keys)
    println(numberMap.values)
[one, two, three]
[1, 2, 3]
2、过滤

filter()

    val numberMap = mapOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)    
	val filter1 = numberMap.filter { (key, value) -> key.startsWith('f') }
    println(filter1)
    val filter2 = numberMap.filterKeys { key -> key.startsWith('f') }
    println(filter2)
    val filter3 = numberMap.filterValues { value -> value > 2 }
    println(filter3)
{four=4}
{four=4}
{three=3, four=4}
3、plus与mins操作
    val numberMap = mapOf("one" to 1, "two" to 2, "three" to 3)
	val map1 = numberMap + ("four" to 4)
    println(map1)
    val map2 = numberMap + mapOf("five" to 5, "six" to 6)
    println(map2)
    val map3 = numberMap - "three"
    println(map3)
{one=1, two=2, three=3, four=4}
{one=1, two=2, three=3, five=5, six=6}
{one=1, two=2}
    val mutableNumberMap = mutableMapOf("one" to 1, "two" to 2)
    mutableNumberMap += Pair("three", 3)//plusAssign
    println(mutableNumberMap)
    mutableNumberMap += mapOf("four" to 4, "five" to 5)
    println(mutableNumberMap)
    mutableNumberMap -= "five"//minusAssign
    println(mutableNumberMap)
{one=1, two=2, three=3}
{one=1, two=2, three=3, four=4, five=5}
{one=1, two=2, three=3, four=4}
4、Map写操作

MutableMap可以提供特定的Map写操作。

Map写操作的一些规则:值可以更新,键永远不会改变;每个键都有与之关联的值,也可以添加删除整个条目。

  1. 添加和更新条目

    put()/putAll(),+=/[]

        val mutableNumberMap = mutableMapOf("one" to 1, "two" to 2)
        mutableNumberMap.put("three", 3)
        println(mutableNumberMap)
        mutableNumberMap.putAll(mapOf("four" to 4, "five" to 5))
        println(mutableNumberMap)
        mutableNumberMap += ("six" to 6)
        println(mutableNumberMap)
        mutableNumberMap["seven"] = 7
        println(mutableNumberMap)
    {one=1, two=2, three=3}
    {one=1, two=2, three=3, four=4, five=5}
    {one=1, two=2, three=3, four=4, five=5, six=6}
    {one=1, two=2, three=3, four=4, five=5, six=6, seven=7}
    
  2. 删除条目

    remove(),-=

        val mutableNumberMap =
            mutableMapOf("one" to 1, "two" to 2, "three" to 3, "four" to 4, "five" to 5, "six" to 6, "againThree" to 3)
        mutableNumberMap.remove("one")
        println(mutableNumberMap)
        mutableNumberMap.keys.remove("two")
        println(mutableNumberMap)
        mutableNumberMap.values.remove(3)//values.remove只删除匹配到的第一个条目
        println(mutableNumberMap)
        mutableNumberMap.keys.removeIf { it.startsWith('f') }
        println(mutableNumberMap)
        mutableNumberMap -= "six"
        println(mutableNumberMap)
    {two=2, three=3, four=4, five=5, six=6, againThree=3}
    {three=3, four=4, five=5, six=6, againThree=3}
    {four=4, five=5, six=6, againThree=3}
    {six=6, againThree=3}
    {againThree=3}
    

你可能感兴趣的:(kotlin,集合,android)