诗林 发表于 2024-11-6 09:22:29

【Android】Kotlin教程(7)

总结:Kotin这门语言是谁计划的,语法很辣鸡,纯属是为了造门语言而造语言。


1.函数式编程

Kotlin 是一种当代的多范式编程语言,支持面向对象编程(OOP)和函数式编程(FP)。函数式编程是一种编程范式,它强调利用纯函数、不可变数据和高阶函数来构建程序。Kotlin 提供了许多特性来支持函数式编程风格,这些特性使得代码更加简洁、易读和易于测试。
2.变换函数map

map变换函数会遍历担当者聚集,让变换器函数作用于聚集里的各个元素,返回结果是包含已修改元素的聚集,会作为链上下一个函数的输入。
map变换函数和定义的变换器函数做完事变后,返回的是一个新聚集,原始聚集没有被修改。
fun main() {
    val animals = listOf("zebra", "giraffe", "elephant", "rat")
    val babies = animals.map { animal -> "A baby $animal is so cute" }
    println(babies)
    //
}
可以将多个 map 操纵链接在一起,以实现更复杂的转换。
val numbers = listOf(1, 2, 3, 4, 5)
val result = numbers.map { it * it }// 计算平方
    .map { "Square of $it" }// 转换为描述性字符串
println(result)// 输出:
3.flatMap

flatMap函数操纵一个聚集的聚集,将其中多个聚会合的元素合并后返回一个包含所有元素的单一聚集。
    val result = listOf(listOf(1, 2, 3), listOf(4, 5, 6), listOf(7, 8, 9))
    val flatMap = result.flatMap { it }
    println(flatMap)
    //
4.过滤函数filter

filter 函数是一个非常有用的高阶函数,用于从聚会合筛选出满意特定条件的元素。它返回一个新的聚集,其中只包含那些通过给定谓词(predicate)测试的元素。filter 函数是函数式编程中的一个根本工具,可以资助你以一种简洁和声明式的方式处理数据。
fun main() {
    val list = listOf(1,2,3,4,5,6,7,8,9,10)
    val result = list.filter { it % 2 == 0 }
    println(result) //
}
fun isEven(number: Int): Boolean {
    return number % 2 == 0
}

val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenNumbers = numbers.filter(::isEven)
println(evenNumbers)// 输出:
5.合并函数zip

zip 函数用于将两个聚集(如列表)中的元素配对,天生一个新的列表。每个新列表的元素是一个包含两个原聚集对应位置元素的 Pair。假如两个聚集的长度不同,那么结果列表的长度将与较短的那个聚集相同。
fun main() {
    val numbers1 = listOf(1, 2, 3)
    val numbers2 = listOf(4, 5, 6)

    val zipped1 = numbers1.zip(numbers2)
    println(zipped1)// 输出: [(1, 4), (2, 5), (3, 6)]


    val names = listOf("Alice", "Bob", "Charlie")
    val ages = listOf(30, 25, 35)

    val zipped2 = names.zip(ages)
    println(zipped2)// 输出: [(Alice, 30), (Bob, 25), (Charlie, 35)]
}
6.合并函数fold

fold 函数是一个非常强大的高阶函数,用于对聚会合的元素进行累积操纵。它从一个初始值开始,依次应用一个函数到每个元素上,并将结果累积起来。fold 是一种减少(reduce)操纵,常用于盘算总和、乘积、最大值、最小值等。
fun main() {
    val numbers1 = listOf(1, 2, 3, 4, 5)
    val sum1 = numbers1.fold(0) { acc, i -> acc + i }
    println(sum1)// 输出: 15


    val numbers2 = listOf(1, 2, 3, 4, 5)
    val product = numbers2.fold(1) { acc, i -> acc * i }
    println(product)// 输出: 120
}
7.序列

在Kotlin中,序列(Sequence)是一个强大的工具,用于处理大数据集或进行复杂的数据转换。
定义:序列是Kotlin标准库中的一个接口,表示一个元素序列。与普通的聚集不同,序列的操纵是惰性的,即元素不会在创建序列时立即被处理,而是会在序列被遍历或消费时才按需天生。这种延迟实行的方式允许我们编写出更高效的数据处理逻辑。
序列的操纵:


[*]中心操纵:序列支持多种中心操纵,如过滤(filter)、映射(map)、扁平化(flatMap)等。这些操纵都是惰性的,只有在序列被消费(如通过toList()、forEach等方法)时,这些操纵才会被实行。
[*]末端操纵:序列的末端操纵会实行原来中心操纵的所有延迟盘算,并返回一个结果,如聚集、数字或其他对象。
// 扩展函数 Int.isPrime(),用于判断一个整数是否是质数
fun Int.isPrime(): Boolean {
    // 遍历从 2 到当前整数减 1 的所有整数
    (2 until this).forEach {
      // 如果当前整数能被任何一个遍历到的整数整除,则返回 false,表示不是质数
      if (this % it == 0) {
            return false
      }
    }
    // 如果没有找到任何能整除当前整数的数,则返回 true,表示是质数
    return true
}


fun main() {
    // 1-5000之内 可以找到1000个素数
    val toList = (1..5000).toList().filter { it.isPrime() }.take(1000)
    println(toList.size) // 670


    val sequence = generateSequence(2) { value -> value + 1 }.filter { it.isPrime() }.take(1000)
    println(sequence.toList().size) // 1000
}
通过利用 Sequence,你可以高效地处理大量数据或无限序列,而不必要一次性加载所有数据到内存中。这对于性能敏感的应用程序非常有用。
8.互操纵性与可空性

互操纵性是指不同系统、软件或编程语言之间能够无缝协作的能力。对于 Kotlin 来说,这意味着 Kotlin 代码可以轻松地与用其他语言(如 Java)编写的代码一起工作。
public class Jhava {
   
    @NotNull
    public String getHello() {
      return "Hello World";
    }


    @Nullable
    public String determineFriendShipLevel(){
      return null;
    }
}

fun main() {
    val adversary = Jhava()
    println(adversary.hello)
    val level = adversary.determineFriendShipLevel()
    println(level?.toLowerCase())
}
9.类型映射

代码运行时,所有的映射类型都会重新映射回对应的Java类型。
    println(adversary.hitPoints.javaClass) // int
10.属性访问

不必要调用相干的setter方法,可以利用赋值语句来设置一个Java字段值。
11.@JvmName

@JvmName 是 Kotlin 提供的一个注解,用于在天生的 Java 字节码中指定方法或属性的具体名称。这在你必要控制 Kotlin 代码天生的 Java 方法名时非常有用,特别是在与 Java 代码互操纵的情况下。
    public static void main(String[] args) {
      System.out.println(Hero.makeProclamation());
    }
@file:JvmName("Hero")fun main() {    val adversary = Jhava()    println(adversary.hello)    val level = adversary.determineFriendShipLevel()    println(level?.toLowerCase())    println(adversary.hitPoints.javaClass) // int
}fun makeProclamation() = "Greeting,beast!" 12.@JvmField

@JvmField 是 Kotlin 提供的一个注解,用于在天生的 Java 字节码中直接暴露一个属性为字段(field),而不是通过 getter 和 setter 方法。这在你必要与 Java 代码进行互操纵时特别有用,因为它允许 Java 代码直接访问 Kotlin 属性,就像访问普通字段一样。
class Spellbook {
    @JvmField
    val spells = listOf("Magic Ms. L","Lay on hans")
}
    public static void main(String[] args) {
      Spellbook spellbook = new Spellbook();
      for (String spell : spellbook.spells){
            System.out.println(spell);
      }
    }
13.@JvmOverloads

@JvmOverloads 是 Kotlin 提供的一个注解,用于天生具有默认参数值的方法的多个重载版本。在 Java 中,方法不支持默认参数,因此 Kotlin 会为每个大概的参数组合天生一个单独的方法。这使得 Kotlin 的默认参数功能可以与 Java 代码无缝集成。
@JvmOverloads
fun handOverFood(leftHand : String = "berrriea", rightHand : String = "beef"){
    println("$leftHand and $rightHand")
}
14.@JvmStatic

1.单例模式:
当你实现单例模式时,可以利用 @JvmStatic 来提供一个静态的方法来获取单例实例。
object Singleton {
    @JvmStatic
    fun getInstance(): Singleton = this
}

// Java 代码
public class Main {
    public static void main(String[] args) {
      Singleton singleton = Singleton.getInstance();
      // 使用 singleton
    }
}
2.工具类
在工具类中,你可以利用 @JvmStatic 来定义静态方法,这样 Java 代码可以直接调用这些方法而不必要创建类的实例。
object StringUtils {
    @JvmStatic
    fun isNullOrEmpty(str: String?): Boolean {
      return str == null || str.isEmpty()
    }

    @JvmStatic
    fun reverse(str: String): String {
      return str.reversed()
    }
}


// Java 代码
public class Main {
    public static void main(String[] args) {
      boolean isEmpty = StringUtils.isNullOrEmpty("test");
      String reversed = StringUtils.reverse("hello");
      // 使用结果
    }
}
3.伴生对象
在 Kotlin 中,伴生对象(companion object)中的成员默认不是静态的。利用 @JvmStatic 可以使这些成员在 Java 中表现为静态成员。
class Spellbook {

    @JvmField
    val spells = listOf("Magic Ms. L","Lay on hans")


    companion object {
      @JvmStatic
      val MAX_SPELL_COUNT = 10
      fun getSpellbookGreeting() = println("I am the Great Grimoire!")
    }
}
System.out.println(Spellbook.getMAX_SPELL_COUNT());
Spellbook.Companion.getSpellbookGreeting();
4.枚举类
enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF);

    companion object {
      @JvmStatic
      fun fromInt(rgb: Int): Color? {
            for (color in values()) {
                if (color.rgb == rgb) {
                  return color
                }
            }
            return null
      }
    }
}
// Java 代码
public class Main {
    public static void main(String[] args) {
      Color color = Color.fromInt(0xFF0000);
      // 使用 color
    }
}
13.@Throws

@Throws 是 Kotlin 中的一个注解,用于声明一个函数大概会抛出哪些受检非常(checked exceptions)。在 Java 中,受检非常必须在方法签名中声明,而在 Kotlin 中,由于语言计划的原因,默认情况下不必要声明受检非常。然而,在某些情况下,特别是当你的 Kotlin 代码必要与 Java 代码互操纵时,利用 @Throws 注解可以明确地指出一个函数大概抛出的非常类型。
import java.io.File
import java.io.IOException

fun readFile(filePath: String): String {
    val file = File(filePath)
    return file.readText()
}
在这个例子中,readText() 方法大概会抛出 IOException。为了明确这一点,你可以利用 @Throws 注解:
import java.io.File
import java.io.IOException

@Throws(IOException::class)
fun readFile(filePath: String): String {
    val file = File(filePath)
    return file.readText()
}
假如你盼望这个函数能够在 Java 代码中被调用,而且 Java 代码能够捕获 IOException,那么利用 @Throws 是必要的:
public class Main {
    public static void main(String[] args) {
      try {
            String content = ExampleKt.readFile("path/to/file.txt");
            System.out.println(content);
      } catch (IOException e) {
            e.printStackTrace();
      }
    }
}
注意:


[*]@Throws 注解只适用于受检非常(checked exceptions)。对于运行时非常(unchecked exceptions),如 NullPointerException 或 IllegalArgumentException,不必要利用 @Throws 注解。
[*]假如一个函数大概会抛出多种类型的受检非常,可以在 @Throws 注解中列出所有大概的非常类型
@Throws(IOException::class, FileNotFoundException::class)
fun readFile(filePath: String): String {
    // 实现
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Android】Kotlin教程(7)