【Kotlin】官网学习笔记

 0、IDEA环境设置:

 

1、基础语法 BasicSyntax

地址:https://kotlinlang.org/docs/basic-syntax.html

一、方法与变量

可以直接编写main方法执行

fun main() {
    println("Hello world!")
}

 

获取main方法的参数并打印:

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

  

完整的方法声明:

fun sum(a: Int, b: Int): Int {
    return a + b
}

  

支持模版语法(提取单个变量,或者是一个表达式)嵌入字符串值:

fun printSum(a: Int, b: Int): Unit {
    println("sum of $a and $b is ${a + b}")
}

 

变量声明可以完整声明,也可以类型推断

val a: Int = 1  // immediate assignment
val b = 2   // `Int` type is inferred

 

二、类和实例

使用class定义一个Kt类:

class Shape

 

kt类没有构造器,直接声明在类上表示需要实例需要构建参数

class Rectangle(var height: Double, var length: Double) {
    var perimeter = (height + length) * 2
}

  

kt的实例的创建是直接调用类名和参数注入获取:

val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")

  

三、循环与分支判断:

if 和 else 通用判断:

fun maxOf(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}

 

可以简单描述行为, 方法的返回类型根据表达式进行自动推断:

fun maxOf(a: Int, b: Int) = if (a > b) a else b

  

使用for循环数组的元素:

val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
    println(item)
}

 

或者循环的是数组的下标,可以通过下标获取元素:

val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
    println("item at $index is ${items[index]}")
}

  

While循环:

val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
    println("item at $index is ${items[index]}")
    index++
}

  

kt使用When表达式来代替switch case语法:

对象可以作为when的入参,提供值或者表达式进行判断,条件成立时执行箭头后的内容

类似else if 执行首个成立的条件后,后续情况不执行

当所有条件都不成立之后走else处理

fun describe(obj: Any): String =
    when (obj) {
        1          -> "One"
        "Hello"    -> "Greeting"
        is Long    -> "Long"
        !is String -> "Not a string"
        else       -> "Unknown"
    }

  

 使用in关键字判断是否在一个范围中:

判断变量x 是否在 1 到 变量y + 1这个范围中

val x = 10
val y = 9
if (x in 1..y+1) {
    println("fits in range")
}

 

范围需要声明起始值和结束值,可以使用变量或者表达式:

另外也可以对in进行取反,表示不在这个范围之内

val list = listOf("a", "b", "c")

if (-1 !in 0..list.lastIndex) {
    println("-1 is out of range")
}
if (list.size !in list.indices) {
    println("list size is out of valid list indices range, too")
}

 

可以设置范围的迭代顺序,或者是调整步进值

for (x in 1..10 step 2) {
    print(x)
}
println()
for (x in 9 downTo 0 step 3) {
    print(x)
}

  

四、集合操作:

list集合使用stream语法更简洁

val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
    .filter { it.startsWith("a") }
    .sortedBy { it }
    .map { it.uppercase() }
    .forEach { println(it) }

  

五、类型检查

使用is关键字对值进行类型匹配判断

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj` is automatically cast to `String` in this branch
        return obj.length
    }

    // `obj` is still of type `Any` outside of the type-checked branch
    return null
}

  

2、编码风格 Idioms

地址:https://kotlinlang.org/docs/idioms.html

一、数据模型类的用法:

详细文档:https://kotlinlang.org/docs/data-classes.html

/* 数据模型类的用法 */

data class Customer2(val name: String, val email: String)

fun main() {
    /* 相同属性的对象,Kt不会重新创建? hashCode值是一样的 */
    val customer2 = Customer2("李四", "1791255334@qq.com")
    val sameOne = Customer2("李四", "1791255334@qq.com")

    /* 提供以下默认方法: copy(), hashCode(), equals(), toString(), component() */

    /* 默认的转字符串方法 */
    val toString = customer2.toString()
    println(toString)

    /* component对应属性值 */
    val component1 = customer2.component1()
    val component2 = customer2.component2()
    println("component1 -> $component1, component2 -> $component2")

    val copiedCustomer1 = customer2.copy()
    val copiedCustomer2 = customer2.copy("王五", "1417274225@qq.com")
    val copiedCustomer3 = customer2.copy(name = "赵六")
    println("c1 -> ${customer2.hashCode()}, sameOne -> ${sameOne.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer1)}")
    println("c2 -> ${copiedCustomer1.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer1)}")
    println("c3 -> ${copiedCustomer2.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer2)}")
    println("c4 -> ${copiedCustomer3.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer3)}")

    /* 支持解构语法 */
    val (name, email) = copiedCustomer3
    println("名称:$name,邮箱:$email")
}

打印结果:

Customer2(name=李四, email=1791255334@qq.com)
component1 -> 李四, component2 -> 1791255334@qq.com
c1 -> 1965046214, sameOne -> 1965046214, isEquals c1 ? true
c2 -> 1965046214, isEquals c1 ? true
c3 -> -1497309957, isEquals c1 ? false
c4 -> 1974389211, isEquals c1 ? false
名称:赵六,邮箱:1791255334@qq.com

Process finished with exit code 0

  

二、方法可设置默认参数

fun main() {
    /* 方法参数支持声明默认值,在调用时可以不需要提供参数 */
    defaultParamFun()
}


fun defaultParamFun(a: Int = 0, b: String = "") { 
    println("a is $a, b is $b")
}

调用结果:

a is 0, b is hello

  

三、过滤逻辑与隐式参数

详细文档见:https://kotlinlang.org/docs/java-to-kotlin-collections-guide.html#filter-elements

fun main() {

    val list = listOf(1, 2, 3, 4, 5, 6)
    /* 1、支持lambda编写过滤逻辑 */
    val positives1 = list.filter { x -> x > 0 }
    /* 2、或者调用隐式参数it编写过滤逻辑 */
    val positives2 = list.filter { it > 0 }

    println("p1 -> $positives1, p2 -> $positives2")

    /* 3、map类型可以同时对key和value编写过滤逻辑 */
    val numbers = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
    val filteredNumbers = numbers.filter { (key, value) -> key.endsWith("1") && value > 10 }
    println(filteredNumbers)

    /* 4、KT支持对元素的类型进行过滤 */
    val numbers2 = listOf(null, 1, "two", 3.0, "four")
    println("All String elements in upper case:")
    /* filterIsInstance指定了泛型的类型后,自动过滤非泛型类型的元素 */
    numbers2.filterIsInstance<String>().forEach {
        println(it.toUpperCase())
    }

    /* 5、逻辑检验 */
    val numbers3 = listOf("one", "two", "three", "four")
    println(numbers3.none { it.endsWith("e") })
    println(numbers3.any { it.endsWith("e") })
    println(numbers3.all { it.endsWith("e") })
}

  

四、IN关键字判断

fun main() {
    /* in 判断 */
    val johnEmail = "john@example.com"
    val emailsList = listOf("1791255334@qq.com", "1791255331@qq.com", "1791255337@qq.com", johnEmail)
    if (johnEmail in emailsList) println("$johnEmail is in emailsList!")
    /* 或者取反判断 */
    if (johnEmail !in emailsList) println("$johnEmail is not in emailsList!")
}

  

五、字符串操作:

详细文档:https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html#concatenate-strings

import kotlin.random.Random

fun main() {
    val a = 100
    /* 1、 改用模版语法实现 */
    println("$a: dsada")

    /* 2、可以对字符串逐个字符遍历 */
    val str = "abcd"
    for (c in str) println(c)

    /* 3、模版语法提供了两种用法 [变量引用] $var 和 [表达式引用] ${var}  */
    println("变量引用式:$a, 表达式引用式:${a + 100}")

    /* 3.1、对模版语法本身需要展示$字符时使用表达式来占位 */
    println("${'$'}_9.99")

    /* 4、KT允许Java方式的字符拼接,但是要求必须是首个变量类型是字符串 */
    val newStr = str + "1334"
    /* 不可以 val newStr = 100 + str 这样使用 */
    println(newStr)

    /* 5、支持字符逃逸符号 */
    val s = "Hello, world!\n"
    println("s -> $s")

    /* 6、原始字符串编写 */
    var text = """
        for (c in "foo")
            print(c)
    """
    println("text -> \n$text")

    /* 7、原始字符串存在前导留白内容,可以使用trimMargin方法处理, 该方法需要提供留白结束符号标记 */
    text = """
    |Tell me and I forget.
    |Teach me and I remember.
    |Involve me and I learn.
    |(Benjamin Franklin)
    """.trimMargin("|")
    println("text -> \n$text")

    /* 8、调用转大写方法 */
    val toUpperCase = str.toUpperCase()
    println(toUpperCase)

    /* 9、KT使用字符构建拼接语法: */
    val countDown = buildString {
        for (i in 5 downTo 1) {
            append(i)
            appendln()
        }
    }
    println(countDown)

    /* 10、将集合元素合并成字符串 */
    val numbers = listOf(1, 2, 3, 4, 5, 6)
    val invertedOddNumbers = numbers
        .filter { it % 2 != 0 }
        .joinToString(separator = ";") {"${-it}"}
    println(invertedOddNumbers)

    /* 11、调用isBlank方法判断是否为空串,然后返回一个默认值 */
    val name = getName().ifBlank { "John Doe" }
    println(name)

    /* 12、替换字符串,常用于清除目标字符,KT单独提供一个API实现 */
    var input = "##place##holder##"
    val result = input.removeSurrounding("##")
    println(result)

    /* 13、正则替换出现数值的字符 */
    val regex = Regex("""\w*\d+\w*""") // raw string
    input = "login: Pokemon5, password: 1q2w3e4r5t"
    val replacementResult = regex.replace(input, replacement = "xxx")
    println("Initial input: '$input'")
    println("Anonymized input: '$replacementResult'")

    /* 15、KT对点号不需要转义 */
    val split = "Sometimes.text.should.be.split".split(".")
    println(split)

    /* 16、字符截取, KT提供了更为简便的API,不通过下标入参,提供指定字符实现 */
    val inputs = "What is the answer to the Ultimate Question of Life, the Universe, and Everything? 42"
    val answer = inputs.substringAfter("?")
    println(answer)

    val inputs2 = "To be, or not to be, that is the question."
    val question = inputs2.substringAfterLast(",")
    println(question)

    /* 17、缩进处理 */
    val result2 = """
        Kotlin
           Java
    """.trimIndent()
    println(result2)

}

fun getName(): String =
    if (Random.nextBoolean()) "" else "David"

  

六、设置扩展方法:

fun main() {
    /* 扩展方法测试 */
    "这是一串字符".testFun()
}

/* 可以声明扩展方法 */
fun String.testFun() {
    println("测试方法调用! 打印字符本体[$this]")
}

  

七、创建一个单例对象:

fun main() {
    println("instance -> $Resource, name -> ${Resource.name}")
}

/* 声明一个单例对象 */
object Resource {
    const val name = "Name"
}

打印结果
instance -> Resource@330bedb4, name -> Name

  

 八、创建抽象类的实例:

abstract class MyAbstractClass {
    abstract fun doSomething()
    abstract fun sleep()
}

fun main() {
    val myObject = object : MyAbstractClass() {
        override fun doSomething() {
            // ...
            println("todo doSomething")
        }

        override fun sleep() { // ...
            println("todo sleep")
        }
    }
    myObject.doSomething()
}

  

 

 

  

 

posted @ 2023-01-19 11:26  emdzz  阅读(64)  评论(0编辑  收藏  举报