Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(上)

简介: Kotlin 学习笔记(二)—— 数据类、枚举类、循环、常用集合及操作符的写法(上)

在上篇笔记中,我们对 Kotlin 的基本类型、关键字、类与对象,以及与 Java 之间互调的内容有了一些认识,这篇笔记来看看 Kotlin 中几种特殊的类,以及集合相关的常用操作。


1. Kotlin 数据类


Kotlin 语言中有个特殊的类叫 数据类这个类型是 Kotlin 专门用来表示一个 Java Bean 的,为啥这么说?因为它帮我们自动生成了一个数据类应该有的方法。比如:getter/setter 方法、toString()、hashCode()、equals()、copy() 方法。举个栗子:

// code 1
data class Book(val id: Int, val name: String) {
}


Kotlin 代码就这么点,然后再看看为我们生成的 Java 代码:(如何查看生成的 Java 代码?找到 AndroidStudio 的 Tools 选项,依次选 Kotlin、show Kotlin ByteCode,然后在新出现的代码窗口点击 Decompile 就可以看到生成的 Java 代码了)

// code 2
public final class Book {
   private final int id;
   @NotNull
   private final String name;
   public final int getId() {
      return this.id;
   }
   @NotNull
   public final String getName() {
      return this.name;
   }
   public Book(int id, @NotNull String name) {
      Intrinsics.checkNotNullParameter(name, "name");
      super();
      this.id = id;
      this.name = name;
   }
   public final int component1() {
      return this.id;
   }
   @NotNull
   public final String component2() {
      return this.name;
   }
   @NotNull
   public final Book copy(int id, @NotNull String name) {
      Intrinsics.checkNotNullParameter(name, "name");
      return new Book(id, name);
   }
   // $FF: synthetic method
   public static Book copy$default(Book var0, int var1, String var2, int var3, Object var4) {
      if ((var3 & 1) != 0) {
         var1 = var0.id;
      }
      if ((var3 & 2) != 0) {
         var2 = var0.name;
      }
      return var0.copy(var1, var2);
   }
   @NotNull
   public String toString() {
      return "Book(id=" + this.id + ", name=" + this.name + ")";
   }
   public int hashCode() {
      int var10000 = this.id * 31;
      String var10001 = this.name;
      return var10000 + (var10001 != null ? var10001.hashCode() : 0);
   }
   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof Book) {
            Book var2 = (Book)var1;
            if (this.id == var2.id && Intrinsics.areEqual(this.name, var2.name)) {
               return true;
            }
         }
         return false;
      } else {
         return true;
      }
   }
}

想不到吧?一行 Kotlin 竟然帮我们干了这么多事!这也说明用 Kotlin 确实能减少代码量,提升 Coding 效率。再看看 Kotlin 数据类的特点。

首先,data class 是一个 final 类,说明 data class 是无法被继承的,哪怕在它前面加 open 关键字也不行。细心的同学可能发现了:这个 Book 并没有 setter 方法呀?没错,那是因为之前在写 Kotlin 代码时,把 id 和 name 两个参数设置为 val 不可变变量了,如果改成 var 再次生成一下,你就会发现有 setter 方法了。

然后,其他的 hashCode、toString、equals、copy 方法都是常规的一些操作,当然,也可以在 data class 里面重写这些方法,达到自己想要的效果。

再看一眼,发现还有两个比较陌生的方法:component1() 和 component2(),和 getter 方法一样啊,为啥?其实这两个方法是 data class 用来解构的,方便用户直接拿到某个对象中的属性值,如下:

// code 3
val book = Book(1, "鲁迅文集")
book.id = 23    // setter 方法
val(bookId, bookName) = book    // 对 book 直接解构
print("bookName = $bookName")    // 输出:“bookName = 鲁迅文集”


如果还有第三个属性的话一样的,就会给你生成 component3(),以此类推。这两个 component 是 data class 自动生成的,如果普通的 class 也想这样解构,也可以,需要使用 operator 关键字,对类中的属性做一个关联:

// code 4
class Car(var brand: String, var price: Double) {    // 普通类 解构
    operator fun component1(): String {
        return this.brand
    }
    operator fun component2(): Double {
        return this.price
    }
}

operator 关键字可以用来重载操作符或者实现一个约定。这里就是实现了一个约定。这样写之后就可以像 data class 一样进行解构了。Kotlin 的这种解构方式用的比较多的地方是在 Map 数据结构中,它不需要像 Java 一样先拿到 Entry 对象,然后才能拿到 key 值和 value 值,直接用这种解构即可。

// code 5
val person = mapOf<String, String>("name" to "Jack", "age" to "23")
for ((key, value) in person) {
    println("key: $key ==== value: $value")
}    // (是不是比 Java 方便多了?)


2. Kotlin 枚举类(密闭类)


Kotlin 中也有枚举类,使用方法与 Java 的枚举类一样,此外,Kotlin 还有一个更加强大的枚举类,称为密闭类,用 sealed 关键字修饰。密闭类可以有自己的子类,而且可以扩展它的子类,例如给子类设置一些参数等,要知道,枚举类是不具有这种特点的:

// code 6
// Kotlin 密闭类(高级枚举类)
sealed class Language {
    object English: Language()
    object Japanese: Language()
    class Chinese(var isDialect: Boolean): Language()    // 是否方言
}


3. Kotlin 循环写法


这个就没啥可说了,直接上代码!

// code 7
    for (i in 1..10) {    // 注意  x..y 表示的是 x<= i <= y,都是闭区间,且 x <= y,否则 i 为空
        print("$i ")    // 输出 1 2 3 4 5 6 7 8 9 10
    }
    for (i in 1 until 10) {    // 区间为 前闭后开
        print("$i ")    // 输出 1 2 3 4 5 6 7 8 9 
    }
    for (i in 10 downTo 1) {    // 递减循环
        print("$i ")    // 输出 10 9 8 7 6 5 4 3 2 1 
    }
    for (i in 1..10 step 2) {    // step 为步进长
        print("$i ")    // 输出 1 3 5 7 9 
    }
    repeat(10) {    // 高阶函数,大括号里表示的是 Lambda 表达式,传进的参数为循环执行这个表达式多少次,it 表示的是目前执行的是第几次,从 0 开始
        print(it)    // 输出 0123456789
    }
    // 平时用的比较多的还是取集合中的元素
    val list = listOf("I","am","Chinese")
    for (str in list) {
        print("$str ")
    }
    for ((index, str) in list.withIndex()){
        print("第${index}元素是$str")
    }


目录
相关文章
|
3天前
|
Kotlin
Kotlin类的定义、构造函数、封装、继承和多态
Kotlin类的定义、构造函数、封装、继承和多态
7 1
|
3天前
|
存储 API Kotlin
Kotlin中的List集合
Kotlin中的List集合
12 2
|
3天前
|
存储 Java Kotlin
Kotlin中的嵌套类、内部类、枚举类、密封类、数据类、单例类、伴生对象
Kotlin中的嵌套类、内部类、枚举类、密封类、数据类、单例类、伴生对象
7 1
|
14天前
|
JavaScript 前端开发 Android开发
kotlin开发 webview如何在收到JS调用后,native返回数据给到JS
这段内容描述了在Hybrid App开发中,使用Kotlin的Compose构建的Web视图(WebView)如何通过JsBridge实现JavaScript与原生代码的交互
|
17天前
|
安全 Android开发 Kotlin
Android面试题之Kotlin的几种常见的类
这篇文章探讨了Kotlin编程语言中的初始化顺序、延迟初始化、惰性初始化、`lateinit`与`by lazy`的区别、初始化注意事项、继承、嵌套类、数据类、单例类和枚举类的使用,以及密封类的概念。文中通过示例代码详细解释了各种特性,并提醒读者关注初始化顺序和线程安全问题。同时,鼓励读者关注作者的公众号“AntDream”获取更多相关文章。
19 1
|
2天前
|
安全 Kotlin
Kotlin中的安全导航操作符?.、空合并运算符?:以及let函数的实践与理解
Kotlin中的安全导航操作符?.、空合并运算符?:以及let函数的实践与理解
3 0
|
3天前
|
存储 API Kotlin
Kotlin中的Map集合
Kotlin中的Map集合
5 0
|
3天前
|
存储 API Kotlin
Kotlin中的Set集合
Kotlin中的Set集合
5 0
|
5天前
|
Kotlin
Kotlin流程控制、循环
Kotlin流程控制、循环
7 0
|
7月前
|
编译器 C++ Kotlin
【Kotlin】基础速览(1):操作符 | 内建类型 | 类型转换 | 字符串模板 | 可变 var 和不可变 val
【Kotlin】基础速览(1):操作符 | 内建类型 | 类型转换 | 字符串模板 | 可变 var 和不可变 val
42 0