首页 安卓 & Kotlin Books Kotlin学徒

8
阵列& Lists 由伊琳娜加拉塔撰写

正如本节简介中所讨论的,集合是灵活的“容器”,允许您将任意数量的值存储在一起。 kotlin中的两个最常见的集合类型是 阵列清单.

阵列

Kotlin中的数组对应于Java中可用的基本数组类型。阵列是键入的,就像常规变量和常量一样,并在内存的连续部分中存储多个值。

在创建第一个阵列之前,需要一些时间才能详细考虑数组是什么以及您可能想要使用的数组。

什么是数组?

数组是相同类型值的有序集合。数组中的元素是 零索引,这意味着第一元素的索引为0,第二元素的索引为1,等等。知道这一点,您可以解决最后一个元素的索引是数组中的值数量少1。

阵列是否有用?

当您想要以特定顺序存储物品时,阵列非常有用。您可能希望将元素排序,或者您可能需要通过索引获取元素而无需迭代整个数组。

创建阵列

The easiest way to create an array is by using a function from the Kotlin standard library, arrayOf(). This is a concise way to provide array values.

val evenNumbers = arrayOf(2, 4, 6, 8)
val fiveFives = Array(5, { 5 }) // 5, 5, 5, 5, 5
val vowels = arrayOf("a", "e", "i", "o", "u")

阵列of primitive types

When using arrayOf() 和 creating arrays with types such as Array<Int>, the resulting array is a list of object types. In particular, if you’re running on the JVM, the integer type will be the boxed Integer class and not the primitive int type. Using primitive types over their boxed counterparts will consume less memory and result in better performance. Unfortunately you can’t use primitives with lists (covered in the next section), so it will be up to you to determine on a case by case basis if the trade off is worth it!

val oddNumbers = intArrayOf(1, 3, 5, 7)
val zeros = DoubleArray(4) // 0.0, 0.0, 0.0, 0.0
val otherOddNumbers = arrayOf(1, 3, 5, 7).toIntArray()

对main的参数()

The main() function is the entry point to Kotlin programs. From Kotlin 1.3 onwards, the main() function has an optional parameter named args that is an Array<String>:

fun main(args: Array<String>) {
}

迭代阵列

To see the arguments passed to main(), you can use the for loop you read about in Chapter 5, “先进的控制流程”.

for (arg in args) {
  println(arg)
}
// do
// re
// mi
// fa
// sol
// la
// ti
// do
args.forEach { arg ->
    println(arg)
}

清单

A型,这是非常相似概念上的阵列是一个 列表。喜欢java, 列表 输入kotlin是一个 界面 that has concrete realizations in types such as ArrayList, LinkedList 和 others. Arrays are typically more efficient than lists in terms of raw performance, but lists have the additional feature of being 动态大小。也就是说,数组是固定大小的,但列表可以设置成长,并根据需要收缩,因为你会学习可变列表时请在后面看到。

创建列表

像阵列,标准库有一个函数来创建一个列表。

val innerPlanets = listOf("Mercury", "Venus", "Earth", "Mars")
val innerPlanetsArrayList =
  arrayListOf("Mercury", "Venus", "Earth", "Mars")
val subscribers: List<String> = listOf()
val subscribers = listOf<String>()

可变名单

再次,标准库不得不在这里使用的功能。

val outerPlanets =
  mutableListOf("Jupiter", "Saturn", "Uranus", "Neptune")
val exoPlanets = mutableListOf<String>()

访问元素

除非您知道如何从中获取值,否则能够创建数组和列表是没用的。在本节中,您将学习几种不同的方法来访问元素。两个数组和列表类似的语法。

使用属性和方法

想象一下,您正在创建一款卡片,您希望将播放器的名称存储在列表中。列表需要将播放器加入或离开游戏的作为更改,因此您需要声明可变列表:

val players = mutableListOf("Alice", "Bob", "Cindy", "Dan")
print(players.isEmpty())
// > false
if (players.size < 2) {
  println("We need at least two players!")
} else {
  println("Let's start!")
}
// > Let's start!
var currentPlayer = players.first()
println(currentPlayer) // > Alice
println(players.last()) // > Dan
val minPlayer = players.minOrNull()
minPlayer.let {
  println("$minPlayer will start") // > Alice will start
}
println(arrayOf(2, 3, 1).first())
// > 2
println(arrayOf(2, 3, 1).min())
// > 1
val maxPlayer = players.maxOrNull()
if (maxPlayer != null) {
  println("$maxPlayer is the MAX") // > Dan is the MAX
}

使用索引

通过使用索引语法来访问数组中的元素的最方便的方法。此语法允许您通过使用其索引在方形括号内直接访问任何值:

val firstPlayer = players[0]
println("First player is $firstPlayer")
// > First player is Alice
val secondPlayer = players.get(1)
val player = players[4] // > IndexOutOfBoundsException

使用范围切片

You can use the slice() method with ranges to fetch more than a single value from an array or list.

val upcomingPlayersSlice = players.slice(1..2)
println(upcomingPlayersSlice.joinToString()) // > Bob, Cindy

检查元素

You can check if there’s at least one occurrence of a specific element by using the in operator, which returns true if it finds the element, and false otherwise.

fun isEliminated(player: String): Boolean {
  return player !in players
}
println(isEliminated("Bob")) // > false
players.slice(1..3).contains("Alice") // false

修改列表

您可以对可变列表进行各种更改,例如添加和删除元素,更新现有值以及将要素更新为不同的顺序。在本节中,您将了解如何与列表合作以与您的游戏中发生的内容匹配。

附加元素

如果新玩家想加入游戏,他们需要注册,他们的名字添加到列表中。礼是加入到现有的四名球员的第一个球员。

players.add("Eli")
players += "Gina"
println(players.joinToString())
// > "Alice", "Bob", "Cindy", "Dan", "Eli", "Gina"
var array = arrayOf(1, 2, 3)
array += 4
println(array.joinToString()) // > 1, 2, 3, 4

插入元素

An unwritten rule of this card game is that the players’ names have to be in alphabetical order. This list is missing a player that starts with the letter F. Luckily, Frank has just arrived. You want to add him to the list between Eli and Gina. To do that, you can use a variant of the add() method that accepts an index as the first argument:

players.add(5, "Frank")

删除元素

During the game, the other players caught Cindy and Gina cheating. They should be removed from the game! You can remove them by name using the remove() method:

val wasPlayerRemoved = players.remove("Gina")
println("It is $wasPlayerRemoved that Gina was removed")
// > It is true that Gina was removed
val removedPlayer = players.removeAt(2)
println("$removedPlayer was removed") // > Cindy was removed

迷你练习

采用 indexOf() to determine the position of the element "Dan" in players.

更新元素

Frank has decided everyone should call him Franklin from now on. You could remove the value "Frank" from the list and then add "Franklin", but that’s too much work for a simple task. Instead, you should use the indexing syntax to update the name.

println(players.joinToString())
// > "Alice", "Bob", "Dan", "Eli", "Frank"
players[4] = "Franklin"
println(players.joinToString())
// > "Alice", "Bob", "Dan", "Eli", "Franklin"
players[3] = "Anna"
players.sort()
println(players.joinToString()) // > "Alice", "Anna", Bob", "Dan", "Franklin"
players.set(3, "Anna")
val arrayOfInts = arrayOf(1, 2, 3)
arrayOfInts[0] = 4
println(arrayOfInts.joinToString()) // > 4, 2, 3

通过列表迭代

这已经迟到了,所以玩家决定停下晚上并继续明天继续。与此同时,您将在单独的清单中保持分数。当您了解地图时,您将调查更好的方法,但现在您可以继续使用列表:

val scores = listOf(2, 2, 8, 6, 1)
for (player in players) {
  println(player)
}
// > Alice
// > Anna
// > Bob
// > Dan
// > Franklin
for ((index, player) in players.withIndex()) {
  println("${index + 1}. $player")
}
// > 1. Alice
// > 2. Anna
// > 3. Bob
// > 4. Dan
// > 5. Franklin
fun sumOfElements(list: List<Int>): Int {
  var sum = 0
  for (number in list) {
    sum += number
  }
  return sum
}
println(sumOfElements(scores))  // > 19

迷你练习

Write a for loop that prints the players’ names and scores.

可用性和收集类型

使用数组,列表和其他集合类型时,应特别考虑无效。例如,是否可为空白可为空白的集合,或者是可用的吗?

var nullableList: List<Int>? = listOf(1, 2, 3, 4)
nullableList = null
var listOfNullables: List<Int?> = listOf(1, 2, null, 4)
列表OfNullables = null // Error: Null can not be a value of a non-null type
var nullableListOfNullables: List<Int?>? = listOf(1, 2, null, 4)
nullableListOfNullables = null

挑战

看看下面的挑战,以测试你的科特林数组和列表的知识。与往常一样,你可以在本章的材料,检查出的解决方案。

1. val array1 = Array<Int>()
2. val array2 = arrayOf()
3. val array3: Array<String> = arrayOf()
val array4 = arrayOf(1, 2, 3)
4. println(array4[0])
5. println(array4[5])
6. array4[0] = 4
val array5 = arrayOf(1, 2, 3)
7. array5[0] = array5[1]
8. array5[0] = "Six"
9. array5 += 6
10. for item in array5 { println(item) }
fun removeOne(item: Int, list: List<Int>): List<Int>
fun remove(item: Int, list: List<Int>): List<Int>
fun reverse(array: Array<Int>): Array<Int>
import java.util.Random  
val random = Random()
fun rand(from: Int, to: Int) : Int {
 return random.nextInt(to - from) + from
}
fun randomized(array: Array<Int>): Array<Int>
fun minMax(numbers: Array<Int>): Pair<Int, Int>?

关键点

  • 阵列 是同一类型的值的有序集合。
  • There are special classes such as IntArray created as arrays of Java primitive types.
  • 清单 类似于阵列但具有被动态大小的附加特征。
  • 您可以添加,删除,更新和插入元素融入 可变名单.
  • 采用 索引 的许多方法来访问和更新的元素或一个。
  • 警惕访问那是出界的指标。
  • You can iterate over the elements of an array or list using a for loop or using forEach.
  • You can check for elements in an array or list using in.
  • 使用可用的列表和名单时,应特别考虑使用可用元素的列出。

然后去哪儿?

现在,你已经了解了科特林数组和列表集合类型,你现在可以移动到学习其他两种常见集合类型: 地图.

有技术问题吗?要报告错误吗? 你可以提出问题并报告错误在我们的官方图书论坛这本书的作者 这里.

有关于网上阅读体验反馈给份额? 如果您对UI,UX,高亮反馈,或者我们的在线读者的其他功能,您可以付款给设计团队与下面的表格:

© 2021 Razeware LLC

您正在阅读的自由,以显示为本章的部分 混淆了 文本。解锁印刷书,以及我们的书籍和视频目录,具有订阅职业raywenderlich.com。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。