Kotlin

Kotlin-数组与集合-Array

2020-10-23  本文已影响0人  AilurusFulgens

Kotlin 为数组添加了一个Array类,使用Array<T>来表示。

声明和创建 Array

  1. arrayOf(vararg elements: T): Array<T>
    声明时传入所有元素
    Kotlin 此时可以推断出数组元素的类型,所以就不需要在 arrayOf() 函数上使用泛型来指定数组元素的类型。
  2. arrayOfNulls(size: Int): Array<T?>
    显式指定数组的长度,数组全部初始化为 null
    Kotlin 此时无法推断出数组元素类型,所以需要在 arrayOfNulls() 函数上使用泛型来指定数组元素的类型。
  3. emptyArray(): Array<T>
    创建一个长度为0的空数组
    Kotlin 此时无法推断出数组元素类型,所以需要在 emptyArray() 函数上使用泛型来指定数组元素的类型。
  4. Array<T> constructor(size: Int, init: (Int) -> T)
    显式指定数组的长度,并可通过 Lambda 表达式来计算个数组元素的值
// 创建包含指定元素的数组
val array1 = arrayOf("Java", "Kotlin", "Go") //["Java", "Kotlin", "Go"]
val intArray1 = arrayOf(1, 2, 400, -90) //[1, 2, 400, -90]

// 创建指定长度,元素为 null 的数组
val array2 = arrayOfNulls<String>(5) //[null, null, null, null, null]
val intArray2 = arrayOfNulls<Int>(10) //[null, null, null, null, null, null, null, null, null, null]

// 创建长度为0的空数组
val array3 = emptyArray<String>() //[]
val intArray3 = emptyArray<Int>() //[]

// 创建指定长度,并使用 Lambda 表达式来初始化元素的数组
val array4 = Array(6) {"Language $it"} //["Language 0", "Language 1", "Language 2", "Language 3", "Language 4", "Language 5"]
val intArray4 = Array(5) {it * 2 + 97} //[97, 99, 101, 103, 105]

当元素为基本类型的值时,Koltin 还为提供了以下8种实例:

实例 初始化
ByteArray byteArrayOf(vararg elements: Byte): ByteArray
ByteArray constructor(size: Int, init: (Int) -> Byte)
ShortArray shortArrayOf(vararg elements: Short): ShortArray
ShortArray constructor(size: Int, init: (Int) -> Short)
IntArray intArrayOf(vararg elements: Int): IntArray
IntArray constructor(size: Int, init: (Int) -> Int)
LongArray longArrayOf(vararg elements: Long): LongArray
LongArray constructor(size: Int, init: (Int) -> Long)
CharArray charArrayOf(vararg elements: Char): CharArray
CharArray constructor(size: Int, init: (Int) -> Char)
FloatArray floatArrayOf(vararg elements: Float): FloatArray
FloatArray constructor(size: Int, init: (Int) -> Float)
DoubleArray doubleArrayOf(vararg elements: Double): DoubleArray
DoubleArray constructor(size: Int, init: (Int) -> Double)
BooleanArray booleanArrayOf(vararg elements: Boolean): BooleanArray
BooleanArray constructor(size: Int, init: (Int) -> Boolean)

使用 Array 中的方法

  1. all(predicate: (T) -> Boolean): Boolean
val array = arrayOf("Java", "Kotlin", "Go")
// 如果所有的元素都满足给定的条件,则返回 true
println(array.all { it.length > 4 }) //false
  1. any(predicate: (T) -> Boolean): Boolean
val array = arrayOf("Java", "Kotlin", "Go")
// 如果至少有一个元素满足给定的条件,则返回 true
println(array.any { it.length > 4 }) //true
  1. 转换成 List
    asList(): List<T>
val array = arrayOf("Java", "Kotlin", "Go")
// 将该数组转换成 List 集合
println(array.asList()) //[Java, Kotlin, Go]
  1. 转换成 Map
    associate(transform: (T) -> Pair<K, V>): Map<K, V>
    associateTo(destination: M, transform: (T) -> Pair<K, V>): M
    associateBy(keySelector: (T) -> K): Map<K, T>
    associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
    associateByTo(destination: M, keySelector: (T) -> K): M
    associateByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M
val array = arrayOf("Java", "Kotlin", "Go")
val map = mutableMapOf(10 to "TypeScript", 5 to "Swift")
// 使用 Lambda 表达式根据数组元素计算,返回 Map<K, V>
println(array.associate { it.length to "$it length" }) //{4=Java length, 6=Kotlin length, 2=Go length}
// 使用 Lambda 表达式根据数组元素计算,并添加到可变 map 集合中,返回修改后的 map
println(array.associateTo(map, { it.length to "$it length" })) //{10=TypeScript, 5=Swift, 4=Java length, 6=Kotlin length, 2=Go length}
// 使用 Lambda 表达式根据数组元素计算,返回 Map<K, V>,其中 V 是数组元素
println(array.associateBy { it.length }) //{4=Java, 6=Kotlin, 2=Go}
// 使用 Lambda 表达式根据数组元素计算,返回 Map<K, V>
println(array.associateBy({ it.length }, { "$it length" })) //{4=Java length, 6=Kotlin length, 2=Go length}
// 使用 Lambda 表达式根据数组元素计算,并添加到可变 map 集合中,返回修改后的 map
println(array.associateByTo(map, { it.length })) //{10=TypeScript, 5=Swift, 4=Java, 6=Kotlin, 2=Go}
// 使用 Lambda 表达式根据数组元素计算,并添加到可变 map 集合中,返回修改后的 map
println(array.associateByTo(map, { it.length }, { "$it length" })) //{10=TypeScript, 5=Swift, 4=Java length, 6=Kotlin length, 2=Go length}
  1. 计算数值型数组的平均值
    average(): Double
val intArray = intArrayOf(2, 67, 6, -1)
// 计算数值型数组的平均值
println(intArray.average()) //18.5
  1. 二分查找(数组元素必须按照升序排序)
    binarySearch(element: Int, fromIndex: Int = 0, toIndex: Int = size): Int
val intAscArray = intArrayOf(-1, 2, 6, 67)
val intArray = intArrayOf(2, 67, 6, -1)
// 用二分法查找元素在数组中出现的位置,要求数组中的元素按升序排列,否则无法得到正确的结果
println(intAscArray.binarySearch(6)) //2,由于数组元素是升序,故结果正确
println(intArray.binarySearch(6)) // -2,由于数组元素无序,故结果错误
  1. 包含
    contains(element: T): Boolean
val array = arrayOf("Java", "Kotlin", "Go")
// 判断该数组是否包含某个元素,可使用 in !in 运算符执行
println(array.contains("Java")) //true
println("Swift" in array) //false
  1. 相等比较
    contentEquals(other: Array<out T>?): Boolean
val array = arrayOf("Java", "Kotlin", "Go")
// 比较两个数组是否相等
val otherArray = arrayOf("Java", "Kotlin", "Go")
println(array.contentEquals(otherArray)) //true
  1. 转换为字符串
    contentToString(): String
val array = arrayOf("Java", "Kotlin", "Go")
// 把数组转换成字符串
println(array.contentToString()) // "[Java, Kotlin, Go]"
  1. 复制数组
    copyOf(): Array<T>
    copyOf(newSize: Int): Array<T?>
    copyOfRange(fromIndex: Int, toIndex: Int): Array<T>
val array = arrayOf("Java", "Kotlin", "Go")
// 复制一个新数组,若指定 size:<= 原size,取前 size 个;> 原size,不足的后面补0(数值类型),false(布尔类型),null(引用类型)
println(array.copyOf().asList()) //[Java, Kotlin, Go]
println(array.copyOf(2).asList()) //[Java, Kotlin]
println(array.copyOf(5).asList()) //[Java, Kotlin, Go, null, null]
// 复制一个新数组,指定区间范围,不可超过原数组的 size
println(array.copyOfRange(1, 2).asList()) //[Kotlin]
  1. 获取元素个数
    count(predicate: (T) -> Boolean): Int
    count(): Int
val array = arrayOf("Java", "Kotlin", "Go")
// 返回该数组给定 Lambda 条件的元素个数,若不指定参数,则返回数组中的元素个数,与 size 相同
println(array.count { it.length > 4 }) //1
println(array.count()) //3
  1. 数组去重
    distinct(): List<T>
val distinctArray = arrayOf("one", "two", "five", "one")
// 该方法用于去掉数组中的重复元素
println(distinctArray.distinct()) //[one, two, five]
  1. 删除数组首位元素
    drop(n: Int): List<T>
    dropLast(n: Int): List<T>
    dropWhile(predicate: (T) -> Boolean): List<T>
    dropLastWhile(predicate: (T) -> Boolean): List<T>
val array = arrayOf("Java", "Kotlin", "Go")
// 去掉数组前面或后面 n 个元素,n >= size 时,返回空集合
println(array.drop(1)) //[Kotlin, Go]
println(array.drop(4)) //[]
println(array.dropLast(1)) //[Java, Kotlin]
println(array.dropLast(4)) //[]
// 去掉数组前面或后面的某些元素,直到不满足条件为止
println(array.dropWhile { it.length >= 4 }) //[Go]
println(array.dropLastWhile { it.length < 4 }) //[Java, Kotlin]
  1. 覆盖元素
    fill(element: T, fromIndex: Int = 0, toIndex: Int = size): Unit
val array = arrayOf("Java", "Kotlin", "Go")
// 将数组从 fromIndex 到 toIndex 索引的元素赋值为 element
array.fill("Swift", 0, array.size)
println(array.asList()) //[Swift, Swift, Swift]
  1. 过滤集合
    filter(predicate: (T) -> Boolean): List<T>
    filterTo(destination: C, predicate: (T) -> Boolean): C
    filterIndexed(predicate: (index: Int, T) -> Boolean): List<T>
    filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C
    filterIsInstance(): List<@kotlin.internal.NoInfer R>
    filterIsInstance(klass: Class<R>): List<R>
    filterIsInstanceTo(destination: C): C
    filterIsInstanceTo(destination: C, klass: Class<R>): C
    filterNot(predicate: (T) -> Boolean): List<T>
    filterNotTo(destination: C, predicate: (T) -> Boolean): C
    filterNotNull(): List<T>
    filterNotNullTo(destination: C): C
val array = arrayOf("Java", "Kotlin", "Go")
// filterXxx,一系列过滤数组元素的方法
// 根据 Lambda 表达式中的条件进行过滤
println(array.filter { it.length > 4 }) //[Kotlin]
// 根据 Lambda 表达式中的条件进行过滤,并添加到 C 中
val otherList = mutableListOf("C++")
println(array.filterTo(otherList, { it.length > 4 })) //[C++, Kotlin]
// 根据 Lambda 表达式中的条件进行过滤,index:索引 s:元素值
println(array.filterIndexed { index, s -> index >=1 && s.length > 1 }) //[Kotlin, Go]
// 根据 Lambda 表达式中的条件进行过滤,index:索引 s:元素值,并添加到另个可变集合 c 中,最终返回 c
val filterOtherArray = mutableListOf("TypeScript", "JavaScript")
println(array.filterIndexedTo(filterOtherArray, { index, s -> index >=1 && s.length > 1 })) //[TypeScript, JavaScript, Kotlin, Go]
// filterIsInstance 返回数组中是 R 的实例的元素,适用于一个抽象类集合中有多种子元素的情况
val animals = arrayOf(
    Dog("Dog 1"),
    Cat("Cat 1"),
    Bird("Bird 1"),
    Dog("Dog 2")
)
println(animals.filterIsInstance<Dog>()) //[Dog 1, Dog 2]
println(animals.filterIsInstance(Dog::class.java)) //[Dog 1, Dog 2]
// filterIsInstanceTo 返回数组中是 R 的实例的元素,并添加到 C 中
val dogs = mutableListOf(
    Dog("Dog a"),
    Dog("Dog b")
)
println(animals.filterIsInstanceTo(dogs)) //[Dog a, Dog b, Dog 1, Dog 2]
println(animals.filterIsInstanceTo(dogs, Dog::class.java)) //[Dog a, Dog b, Dog 1, Dog 2, Dog 1, Dog 2]
// 返回一个与给定条件不匹配的 List 集合,与 filter 方法取反
println(animals.filterNot { it.name == "Dog 1" }) //[Cat 1, Bird 1, Dog 2]
// 返回一个与给定条件不匹配的 List 集合,并添加到 C 中,与 filterTo 方法取反
val otherAnimals = mutableListOf(
    Dog("Dog a"),
    Cat("Cat a"),
    Bird("Bird a"),
    Dog("Dog b")
)
println(animals.filterNotTo(otherAnimals, { it.name == "Dog 1" })) //[Dog a, Cat a, Bird a, Dog b, Cat 1, Bird 1, Dog 2]
// 过滤掉 null,返回一个没有 null 的 List
val nullableArray = arrayOf("aaa", "bbb", null, "ccc")
println(nullableArray.filterNotNull()) //[aaa, bbb, ccc]
// 过滤掉 null,并添加到 C 中,返回 C
val otherNullableList = mutableListOf("AAA", null, "BBB")
println(nullableArray.filterNotNullTo(otherNullableList)) //[AAA, null, BBB, aaa, bbb, ccc]

abstract class Animal(var name: String)

class Dog(name: String) : Animal(name) {
    override fun toString(): String = name
}

class Cat(name: String) : Animal(name) {
    override fun toString(): String = name
}

class Bird(name: String) : Animal(name) {
    override fun toString(): String = name
}
  1. 查找元素
    find(predicate: (T) -> Boolean): T?
    findLast(predicate: (T) -> Boolean): T?
val array = arrayOf("Java", "Kotlin", "Go")
// findXxx 一系列用于查找元素的方法
println(array.find { it.length > 2 }) //Java
println(array.findLast { it.length > 2 }) //Kotlin
  1. 返回第一个/最后一个元素
    first(): T
    first(predicate: (T) -> Boolean): T
    firstOrNull(): T?
    firstOrNull(predicate: (T) -> Boolean): T?
    last(): T
    last(predicate: (T) -> Boolean): T
    lastOrNull(): T?
    lastOrNull(predicate: (T) -> Boolean): T?
val array = arrayOf("Java", "Kotlin", "Go")
// firstXxx(正序遍历) lastXxx(倒序遍历)
// 返回数组第一个元素,若是空数组,则会抛异常
println(array.first()) //Java
// 返回满足条件的第一个元素,若都不满足条件,则会抛异常
println(array.first { it.length > 2 }) //Java
// 返回数组第一个元素,若是空数组,则返回 null
println(array.firstOrNull()) //Java
// 返回满足条件的第一个元素,若都不满足条件,则返回 null
println(array.firstOrNull { it.length > 6 }) //null
// 返回数组最后一个元素,若是空数组,则会抛异常
println(array.last()) //Go
// 返回满足条件的最后一个元素,若都不满足条件,则会抛异常
println(array.last { it.length > 2 }) //Kotlin
// 返回数组最后一个元素,若是空数组,则返回 null
println(array.lastOrNull()) //Go
// 返回满足条件的最后一个元素,若都不满足条件,则返回 null
println(array.lastOrNull { it.length > 6 }) //null
  1. 增值运算
    fold(initial: R, operation: (acc: R, T) -> R): R
    foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R
    foldRight(initial: R, operation: (T, acc: R) -> R): R
    foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R): R
    runningFold(initial: R, operation: (acc: R, T) -> R): List<R>
    runningFoldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List<R>
val array = arrayOf("Java", "Kotlin", "Go")
// 将元素作为参数传入 operation 表达式后执行计算,将结果作为下一个数组的 initial,直到执行完所有元素,并返回最终值
// fold 正序遍历 acc:增值器,s:元素
println(array.fold("", { acc, s -> s + acc })) //GoKotlinJava
// foldIndexed 正序遍历 index:索引,acc:增值器,s:元素
println(array.foldIndexed("", { index, acc, s -> "$index$s$acc" })) //2Go1Kotlin0Java
// foldRight 倒序遍历 s:元素,acc:增值器
println(array.foldRight("", { s, acc -> s + acc })) //JavaKotlinGo
// foldRightIndexed 倒序遍历 index:索引,s:元素,acc:增值器
println(array.foldRightIndexed("", { index, s, acc -> "$index$s$acc" })) //0Java1Kotlin2Go
// runningFold 正序遍历 acc:增值器,s:元素 返回 List
println(array.runningFold("", { acc, s -> s + acc })) //[, Java, KotlinJava, GoKotlinJava]
// runningFoldIndexed 正序遍历 index:索引,acc:增值器,s:元素 返回 List
println(array.runningFoldIndexed("", { index, acc, s -> "$index$s$acc" })) //[, 0Java, 1Kotlin0Java, 2Go1Kotlin0Java]
  1. 获取元素的索引
    indexOf(element: T): Int
    lastIndexOf(element: T): Int
    indexOfFirst(predicate: (T) -> Boolean): Int
    indexOfLast(predicate: (T) -> Boolean): Int
val array = arrayOf("Java", "Kotlin", "Go")
// 正序/倒序搜索元素 element 在数组中的索引
println(array.indexOf("Java")) //0
println(array.lastIndexOf("Java")) //0
// 正序/倒序搜索元素,当满足条件时
println(array.indexOfFirst { it.isNotEmpty() }) //0
println(array.indexOfLast { it.isNotEmpty() }) //2
  1. 获取元素的交集或并集
    intersect(other: Iterable<T>): Set<T>
    union(other: Iterable<T>): Set<T>
val array = arrayOf("Java", "Kotlin", "Go")
val otherMutableList = mutableListOf("Java", "Swift", "C++")
// 获取两个数组的交集
println(array.intersect(otherMutableList)) //[Java]
// 获取两个数组的并集
println(array.union(otherMutableList)) //[Java, Kotlin, Go, Swift, C++]
  1. 添加元素或数组
    plus(element: T): Array<T>
    plusElement(element: T): Array<T>
    plus(elements: Collection<T>): Array<T>
val array = arrayOf("Java", "Kotlin", "Go")
// 添加元素或数组
println(array.plus("Dart").contentToString()) //[Java, Kotlin, Go, Dart]
println(array.plusElement("Dart").contentToString()) //[Java, Kotlin, Go, Dart]
println(array.plus(otherMutableList).contentToString()) //[Java, Kotlin, Go, Java, Swift, C++]
  1. 获取最大/最小值
    maxOrNull(): T?
    minOrNull(): T?
val array = arrayOf("Java", "Kotlin", "Go")
// 按照自然排序规则,获取数组中元素最大值/最小值
println(array.maxOrNull()) //Kotlin
println(array.minOrNull()) //Go
  1. 排序
    sort(): Unit
    sortWith(comparator: Comparator<in T>): Unit
val array = arrayOf("Java", "Kotlin", "Go")
// 数组排序,按自然排序
array.sort()
println(array.contentToString()) //[Go, Java, Kotlin]
// 数组排序,按自定义规则排序
array.sortWith { s1, s2 -> s2.length - s1.length }
println(array.contentToString()) //[Kotlin, Java, Go]

Array 的遍历

  1. for(item in array) { ... }
    for-in 遍历,遍历元素
  2. for(index in array.indices) { ... }
    for-in 遍历,遍历下标,indices 方法返回数组的索引区间
  3. for ((index, item) in array.withIndex()) { ... }
    withIndex() 方法返回一个 Iterable 对象,该对象的所有元素都是 IndexedValue
  4. array.forEach { ... }
    forEach Lambda 表达式遍历
val array1 = arrayOf("Java", "Kotlin", "Go")
// for-in 遍历,遍历元素
for (item in array1) {
    println(item)
}

// for-in 遍历,遍历下标
for (index in array1.indices) {
    println(array1[index])
}

// for-in 遍历,使用 withIndex
for ((index, item) in array1.withIndex()) {
    println("第 $index 个元素是 $item")
}

// forEach 遍历
array1.forEach {
    println(it)
}

多维数组

// 二维数组:所有元素都是一维数组,本质还是一维数组
val twoDimensionalArray = arrayOf(arrayOf(1, 2), arrayOf(3, 4), arrayOf(5, 6))
twoDimensionalArray.forEach {
    println(it.contentToString())
}
//[1, 2]
//[3, 4]
//[5, 6]

// 三维数组:所有元素都是二维数组,本质还是一维数组
val threeDimensionalArray = arrayOf(
    arrayOf(arrayOf(1, 2), arrayOf(3, 4), arrayOf(5, 6)),
    arrayOf(arrayOf(7, 8), arrayOf(9, 10), arrayOf(11, 12))
)
threeDimensionalArray.forEach {
    it.forEach { second ->
        println(second.contentToString())
    }
}
//[1, 2]
//[3, 4]
//[5, 6]
//[7, 8]
//[9, 10]
//[11, 12]

上一篇 下一篇

猜你喜欢

热点阅读