Kotlin-基础语法练习三
接上一篇博客
Array & String
Kotlin Array
数组是几乎所有编程语言中最基本的数据结构之一。数组背后的思想是在单个变量名称下存储具有相同数据类型(如整数或字符串)的多个项。在编程中,数组用于组织数据,以便对一组相关的值进行排序或搜索。
创建数组
- 使用arrayOf()函数
可以使用标准库函数arrayOf()将元素的值传递给该函数来创建数组。
val num = arrayOf(1, 2, 3, 4) //隐式类型声明
val num = arrayOf<Int>(1, 2, 3) //显式类型声明
Example
package org.examplefun main(args:Array<String>){var arrayname = arrayOf(1,2,3,4,5)for(i in 0..arrayname.size-1){print(" "+arrayname[i])}println()var arrayname2 = arrayOf<Int>(10,20,30,40,50)for (i in 0..arrayname2.size-1){print(" "+arrayname2[i])}
}
Output
1 2 3 4 510 20 30 40 50
- 使用Array构造函数
由于Array是Kotlin中的一个类,我们也可以使用Array构造函数来创建数组。构造函数接受两个参数:
- 数组的大小,和
- 接受给定元素的索引并返回该元素的初始值的函数。
语法
val num = Array(3, {i-> i*1})
Example
package org.examplefun main(){val arrayname = Array(5,{i->i+1})println(arrayname)for (i in 0..arrayname.size-1){print(" "+arrayname[i])}
}
Output
[Ljava.lang.Integer;@404b9385
1 2 3 4 5
- 通过工厂方法创建数组
val num = intArrayOf(1, 2, 3, 4)
byteArrayOf()
charArrayOf()
shortArrayOf()
longArrayOf()
访问和修改数组
- 使用get()和set()方法
语法
val x = num.get(0)
num.set(1, 3)
- 使用索引运算符[]
val x = num[1]
num[2] = 5;
Example
fun main()
{ // declare an array using arrayOf()val num = arrayOf(1, 2, 3, 4, 5)num.set(0, 10) // set the first element equal to 10num.set(1, 6) // set the secondelement equal to 6println(num.get(0)) // print the first element using get()println(num[1]) // print the second element using []
}
Output:
10
6
数组遍历
语法
for(i in num.indices){println(num[i])
}
Example
// Traversing an array
fun main()
{val num = arrayOf<Int>(1, 2, 3, 4, 5)num.set(0, 10)num.set(1, 6)for (i in num.indices){println(num[i])}
}
Output
10
6
3
4
5
- foreach循环
arrayname.forEach({index->println(index)})
Example
package arrayfun main(args:Array<String>){val arrayname = arrayOf<Int>(1,2,3,4,5,6,7,8,9,10)arrayname.forEach { e->System.out.println(e.toString()) }
}
Output:
1
2
3
4
5
6
7
8
9
10
向函数传递变量参数
在很多情况下,我们需要将变量参数传递给函数。在Kotlin中,您可以通过使用可变参数声明函数来向函数传递可变数量的参数。类型为T的可变形参在函数体内部表示为类型为T的数组(array )。在本文中,我们将介绍实现这一目标的所有方法。我们将通过几个示例来演示如何使用Kotlin的这个特性。
Example
下面的步骤将演示如何向函数传递可变数量的参数。使用vararg,我们可以将逗号分隔的参数传递给函数,其中我们已经将方法的单个参数定义为vararg,如下例所示:
package arrayfun main(args: Array<String>) {someMethod("as","you","know","this","works")
}fun someMethod(vararg a:String) {for (a_ in a)println(a_)
}
Output:
as
you
know
this
works
假设有一个函数,它接受一个可变参数 vararg,你可以使用 * 运算符将数组传递给这个函数,而不需要手动拆解数组
package arrayfun printNumbers(vararg numbers: Int) {for (number in numbers) {println(number)}
}fun main(args: Array<String>) {val nums = intArrayOf(1, 2, 3, 4, 5)// 使用 spread operator 将数组传递给 vararg 参数printNumbers(*nums) // 展开数组作为参数传递
}
Output:
1
2
3
4
5
-
- vararg 的作用:
vararg
关键字用来定义一个可变参数的方法,它允许你传递多个值,Kotlin 会自动将这些值收集到一个数组中。这对于你不确定会传递多少个参数的情况特别有用。
-
- *(spread operator):
*
运算符告诉编译器将一个数组的内容解开,作为单独的元素传递给一个接受可变参数的方法。换句话说,*
是让你将一个已有的数组变成多个独立的参数传递给函数。
-
- 传递其他参数(例如命名参数):
除了 vararg
参数,有时你还需要传递其他类型的参数,例如命名参数、普通参数等。在这种情况下,你可以使用 *
运算符来处理 vararg
参数,同时还可以传递其他参数。
Example
fun printDetails(name: String, age: Int, vararg numbers: Int) {println("Name: $name")println("Age: $age")println("Numbers:")for (number in numbers) {println(number)}
}fun main() {val nums = intArrayOf(1, 2, 3, 4, 5)// 这里除了传递一个数组给 vararg 参数,还传递了其他普通参数printDetails(name = "Alice", age = 30, *nums) // 解包数组并传递其他参数
}
Output
Name: Alice
Age: 30
Numbers:
1
2
3
4
5
Example2:
package arrayfun main (args: Array<String>) {val list = arrayOf( "as", "you", "know", "this", "works")someMethod ( 3, *list)
}fun someMethod (b: Int, vararg a: String) {for (a_ in a) {println(a_)}
}
Output:
as
you
know
this
works
Example3:
package arrayfun main (args: Array<String>) {someMethod5 ("3", "as", "you", "know", "this", "works")
}fun someMethod5 (b: String, vararg a: String) {println ("b: " + b)for (a_ in a) {println (a_)}
}
Output:
b: 3
as
you
know
this
works
通常,变量是传递的最后一个参数,但是如果我们想在变量之后传递其他参数呢?当然可以,但他们必须被命名。这就是为什么下面的代码不能编译
fun main (args: Array<String>) {someMethod ("3", "as", "you", "know", "this", "works", "what")
}fun someMethod (b: String, vararg a: String, c: String) {printin ("b: " + b)for (a_ in a) {println(a_)}println("c: " + c)
}
Output:
No value passed for parameter 'c'.
它不会编译,因为传递给它的最后一个字符串被认为是vararg
的一部分,并且编译器会抛出一个错误,因为我们没有传递c
的值。为了正确地做到这一点,我们需要将c
作为命名参数传递,如下所示:
package arrayfun main (args: Array<String>) {someMethod6 ("3", "as", "you", "know", "this", "works", c="what")
}fun someMethod6 (b: String, vararg a: String, c: String) {println ("b: " + b)for (a_ in a) {println(a_)}println("c: " + c)
}
Output:
b: 3
as
you
know
this
works
c: what
变量修饰符告诉编译器接受所有以逗号分隔的参数并将它们包装到一个数组中,而*
(展开操作符)将展开数组的元素并将它们作为参数传递。
如果我们希望第一个参数有一个默认值,就像下面的例子:
package arrayfun main (args: Array<String>) {someMethod7 ("3", "as", "you", "know", "this", "works")
}fun someMethod7 (b: String = "x", vararg a: String) {println ("b: " + b)for (a_ in a){println (a_)}
}
我们希望所有参数都被视为vararg
的一部分,但编译器将第一个参数读取为b
。在这种情况下,命名传递的参数可以解决问题:
package arrayfun main (args: Array<String>) {someMethod8 (a =*arrayOf ("3", "as", "you", "know", "this", "works"))
}fun someMethod8 (b: String = "x", vararg a: String) {println ("b: " + b)for (a_ in a){println (a_)}
}
在前面的代码中,编译器理解没有传递b的值,它采用默认值。类似地,如果您希望在函数中有两个变量,则需要传递命名参数。
使用Map函数变换列表
Kotlin是由JetBrains开发的一种静态类型的通用编程语言,它已经构建了世界级的IDE,如IntelliJ IDEA, PhpStorm, Appcode等。它是JetBrains在2011年首次引入的,是一种针对JVM的新语言。Kotlin
是一种面向对象的语言,是一种比Java“更好的语言”,但仍然可以与Java代码完全互操作。在本文中,我们将学习如何使用Kotlin中的map函数
转换列表,以及如何使用我们喜欢的标准过滤列表。我们将使用lambda函数
,它为函数式编程提供了一种很好的方法
Example:
首先,让我们看看如何在列表上使用过滤器函数。过滤器函数返回一个列表,其中包含与给定表达式匹配的所有元素。我们将创建一个数字列表,并根据偶数或奇数对列表进行过滤。过滤器方法适合不可变集合,因为它不修改原始集合,而是返回一个新集合。在过滤器方法中,我们需要实现表达式。与条件一样,表达式作用于被过滤的列表。例如,我们知道偶数项将用表达式 (x%2==0)。因此,相应的过滤器方法看起来像这样:
package arrayfun main(){val listOfNumbers = listOf (1, 2, 3, 4, 5, 6, 7, 8, 9)var evenList = listOfNumbers.filter {it %2==0}println (evenList)
}
Output:
[2, 4, 6, 8]
过滤器函数的另一个变体是filterNot
,顾名思义,它返回一个列表,其中包含与给表达式不匹配的所有元素。另一个很酷的lambda函数
是map
。它转换列表并返回一个新列表:
package arrayfun main(){val listOfNumbers = listOf (1, 2, 3, 4, 5, 6, 7, 8, 9)var transformedList = listOfNumbers.map {it*2}println(transformedList)
}
Output:
[2, 4, 6, 8, 10, 12, 14, 16, 18]
map函数
的一个变体是map Indexed
。它在其构造中提供索引和项:
package arrayfun main(){val listOfNumbers=listOf (1, 2, 3, 4, 5)val map=listOfNumbers.mapIndexed { index, it-> it*index}println(map)
}
Output:
[0, 2, 6, 12, 20]
- 转换 Map
像Kotlin
中的其他集合类型一样,Map
也有许多方法可以进行转换,以满足我们应用的需求。接下来,我们将展示几个常用的操作。以下是我们库存Map
的初始数据:
val inventory = mutableMapOf("Vanilla" to 54,"Chocolate" to 64,"Strawberry" to 39,
)
Kotlin
提供了几种用于过滤 Map
的方法。要根据键或值进行过滤,可以分别使用 filterKeys
和 filterValues
。如果我们需要同时根据键和值进行过滤,可以使用 filter
方法。下面是一个根据剩余数量过滤冰淇淋库存的示例:
val lotsLeft = inventory.filterValues { qty -> qty > 10 }
assertEquals(setOf("Vanilla", "Chocolate"), lotsLeft.keys)
-
filterValues 方法将给定的表达式应用于 Map 中每个条目的值。经过过滤后,返回的是符合表达式条件的条目集合。
-
如果我们想过滤掉不符合该条件的条目,可以使用 filterNot 方法。
Kotlin String
字符数组称为字符串。Kotlin字符串类似于Java字符串,但增加了一些新功能。它们也是不可变的,这意味着我们不能改变字符串的元素和长度。
Kotlin中的String类定义为:
class String : Comparable<String>, CharSequence
要在Kotlin中声明一个字符串,我们需要使用双引号(" ");单引号不允许定义字符串。
语法
var variable_name = "Hello, Kotlin"
or
var variable_name : String = "Kotlin"
创建一个空字符串:
要在Kotlin中创建一个空字符串,我们需要创建string类的一个实例。
var variable_name = String()
字符串元素和模板
- 字符串元素
字符串中出现的字符、数字或任何其他符号称为字符串的元素。我们可以很容易地使用string[index]访问字符串的元素。元素存储在从索引0到(string)的字符串长度- 1。
在Kotlin中有三种方法可以访问字符串元素- 1. 使用索引:返回指定索引处的字符。
- 2. 使用get函数:返回作为参数传递给get函数的指定索引处的字符。
- 3. 在String对象上迭代:使用循环访问String对象中的字符。
Kotlin程序访问字符串的元素
package arrayfun main(args: Array<String>){// accessing string// elements one by onevar str = "Hello"println(str[0])println(str[1])println(str[2])println(str[3])println(str[4])// accessing the string// elements using for loopvar str2 = "Kotlin"for(i in str2.indices){print(str2[i]+" ")}
}
Output:
H
e
l
l
o
K o t l i n
- 字符串模板
字符串模板表达式是求值的一段代码,其结果返回到字符串中。两种字符串类型(转义字符串和原始字符串)都包含模板表达式。字符串模板以美元符号$开头,该符号由变量名或花括号中的任意表达式组成
package arrayfun main(args: Array<String>) {var n = 10println("The value of n is $n")// using stringval str = "Kotlin"println("$str is a string which length is ${str.length}")
}
Output:
The value of n is 10
Kotlin is a string which length is 6
字符串长度
length:返回字符串的长度。
var s =" String"
println(s.length)
字符串通过索引获取元素
get(index):返回特定索引处的字符。
s.get(3) // Output: - i
字符串的子序列
子序列(start, end):返回从start开始到end结束但不包括end的子字符串。
s.subSequence(1, 4) // Output: - tri
字符串CompareTo
str. compareto (string):如果str == string则返回0。
var s1 = "Hello"
var s2 = "Hello"
println(s1.compareTo(s2)) // Output:0
参数:
•s1:字符串1,用于比较
•s2:用于比较的字符串2
返回:
•如果string1 > string2,则返回正数
•如果string1 < string2,则返回负数
•如果string1 == string2,返回0
Kotlin程序使用上述属性和函数
package arrayfun main(args: Array<String>) {var g = "Hello World"var e = "Kotlin"println(g.length)println(g.get(4))println(g.subSequence(0, 5))println(g.compareTo(e))
}
Output:
11
o
Hello
-3
字符串字面值
Kotlin -中有两种类型的字符串字面值
- 1. 转义的字符串
- 2. 原始字符串
- 转义的字符串
转义字符串用双引号(“…”)声明,它可能包含转义字符,如\n, \t等。
fun main(args: Array<String>) {// escaped stringval str = "World \n is \n amazing"println(str)
}
Output:
World is amazing
- 原始字符串-多行字符串
原始字符串放在三引号内(“”“…”“”),并且没有转义字符。它提供了将字符串写入多行的功能,因此它也被称为多行字符串。
原始字符串的Kotlin程序:
fun main(args: Array<String>) {// raw string - multiline stringvar str = """My|name|is|Yash""".trimMargin()println(str)
}
My
name
is
Yash
转义字符-一些转义字符是:
•":双引号
•\r:用于回车
•\n:表示换行符
•':用于单引号
•\:用于反斜杠
•\t:用于TAB
•\b:表示退格
字符串相等性
Kotlin 提供了一个额外的特性,用于以两种不同的方式比较特定类型的实例。这一特性使得 Kotlin 与其他编程语言有所不同。
相等性有两种类型:
- 结构相等性 (Structural Equality)
结构相等性是通过 == 运算符和其反运算符 != 来检查的。默认情况下,包含 x == y 的表达式会被转换为该类型的 equals() 函数调用。
- 引用相等性 (Referential Equality)
Kotlin 中的引用相等性是通过 === 运算符和其反运算符 !== 来检查的。只有当两个实例指向内存中的同一位置时,才返回 true。当在运行时对转换为原始类型的类型进行使用时,=== 检查会被转换为 == 检查,而 !== 检查则会被转换为 != 检查。
Kotlin程序演示了结构和引用的相等性
fun main(args: Array<String>) {var x = "Hello"var y = "Hello"var z = "Kotlin"println(x===y) // true , as both are pointing to the same StringPoolprintln(x==z) //false since values are not equalprintln(x===z) // false
}
Output:
true
false
false