===比较引用
==比较值
集合类型
不可变List:List
可变List:MutableList
不可变Map:Map
可变Map:MutableMap
不可变Set:Set
可变Set:MutableSet
创建集合
val map:Map
val map2:Map
val intList:List
val intList2:MutableList
val intList3 = ArrayList
只有可变的才能添加、删除元素
集合遍历
for(i in 0..10){}
for(e in list){}
while{}
do {
} while
list.forEach{
}
集合可额外直接通过+-来添加、删除元素
val stringList = ArrayList
stringList += "a"
stringList -= "a"
还可以通过[]进行下标索引取值、赋值
stringList[1] = "b"
特殊集合类型:Pair标识一对值、Triple表示一个三值集合
val pair = "hello" to "Kotlin
val pair = Pair("Hello", "Kotlin")
val first = pair.first
val second = pair.second
val (x, y) = pair
val triple = Triple("x" 2, 3.0)
val first = triple.first
val second = triple.second
val third = triple.third
val (x, y, z) = triple
数组类型
整形:IntArray、
整形装箱:Array
字符:CharArray
字符装箱:Array
字符串:Array
数组创建
val a = IntArray(2)
a.size:数组长度
a[0]:引用数组值
遍历与集合一样
区间类型
val intRange = 1..10 闭区间,包括起止值
val intRangeExclusive = 1 until 10 不包括结束值
倒序区间
val intRangeReverse = 10 downTo 1 包括起止值
步长
val intRangeWithStep = 1..10 step 2
函数定义
fun main(args:Array
println(args.contentToString())
}
其中函数返回值为Unit可以省略,跟Java void类型一样
函数引用
fun foo() {} val f:()-> Unit= ::foo
fun foo(p0: Int): String {} val g:(Int)->String = ::foo
class Foo {
fun bar(p0: String, p1: Long): Any{
}
}
val h:(Foo, String, Long)->Any = Foo::bar
其中,等号右侧冒号前面有类名的是类对象的方法引用,在调用时也要传对象实例才行
val foo = Foo()
h(foo, "qq", 1)
变长参数:vararg
fun multiParameters(vararg ints: Int) {
}
函数默认参数
fun defaultParameter(x: Int, y: Int, z: Long = 0L) {
}
如果默认参数不是最后一个,必须使用具体参数名
fun defaultParamter(x: Int = 5, y: String, z: Long = 0L) {
}
defaultParamter(y = "hello")
高级函数,函数的参数可以是另一个函数
fun test(p: (Foo, String, Long)-> Any) {
}
val x = Foo::bar
test(x)
运算符重载
kotlin支持运算符重载,类似C++,kotlin中的==、+、>、[]、包括函数调用符号()都是kotlin中内置好的重载运算符
fun main(args: Array) { val value = "Hello Kotlin" println(value - "Hello") println(value * 2) val star = "*" println(star * 20) println(value / 3) println(value / "l") println(value / "ld") } //减 operator fun String.minus(right: Any?) = this.replaceFirst(right.toString(), "") //乘 operator fun String.times(right: Int): String { return (1..right).joinToString("") { this } } //除 operator fun String.div(right: Any): Int { val right = right.toString() return this.windowed(right.length, 1, transform = { it == right }).count { it } }
重载运算符的定义特点就是类定义扩展方法,方法名和运算符对应的描述,可以通过https://kotlinlang.org/docs/reference/operator-overloading.html#unary-prefix-operators
进行查询,方法前使用operator关键字修饰
lambda表达式
kotlin里的lambda表达式是一个匿名函数的语法糖,因此它的类型其实就是对应的函数类型
val func: ()->Unit = fun() {
println("hello")
}
val func2 = {p:Int->
println(p)
"hello"
}
println(func2(1))
中缀函数,如果函数:是成员函数/扩展函数、只有一个参数、标有infix关键字,就可以认为是一个中缀函数
class Structure() { infix fun createPyramid(rows: Int) { var k = 0 for (i in 1..rows) { k = 0 for (space in 1..rows - i) { print(" ") } while (k != 2 * i - 1) { print("* ") ++k } println() } } }
fun main(args: Array) { val p = Structure() p createPyramid 4 }
其本质还是类的扩展方法,前面加infix关键字,可能是为了实现更加语义化的书写方式
高阶函数
高阶函数简单来说就是函数的参数可传递另一个函数,常见于forEach表达式
val intArray = IntArray(5) { it + 1}
intArray.forEach {
println(it)
}
intArray.forEach(::println)
intArray.forEach {
println("Hello % it")
}
例子:定义一个函数打印方法耗时
fun cost(block: () -> Unit) { val start = System.currentTimeMillis(); block() println("${System.currentTimeMillis() - start}ms") } fun fibonacci(): () -> Long { var first = 0L var second = 1L return { val next = first + second val current = first first = second second = next current } }
cost { val fibonacciNext = fibonacci() for(i in 0..10) { println(fibonacciNext()) } }
内联函数
添加inline关键字的函数标记为内联函数,内联函数的特点是,代码会被直接插入到调用处,编译的代码反编译的结果就是代码直接插入到调用处的结果。内联函数效率高一些。
inline fun cost(block: () -> Unit) { val start = System.currentTimeMillis(); block() println("${System.currentTimeMillis() - start}ms") }
cost { println("Hello") }
编译后等价于
val start = System.currentTimeMillis();
block()
println("${System.currentTimeMillis() - start}ms")
内联函数的返回
val ints = intArrayOf(1, 2, 3, 4)
ints.forEach{
if(it == 3) return @forEach
println("Hello $it")
}
这里面的return等价于continue,因为在非循环体内,无法使用continue,所以使用return@方法名可返回该函数的上一层。